github.com/shuguocloud/go-zero@v1.3.0/core/mapping/unmarshaler_test.go (about)

     1  package mapping
     2  
     3  import (
     4  	"encoding/json"
     5  	"strconv"
     6  	"strings"
     7  	"testing"
     8  	"time"
     9  
    10  	"github.com/stretchr/testify/assert"
    11  	"github.com/shuguocloud/go-zero/core/stringx"
    12  )
    13  
    14  // because json.Number doesn't support strconv.ParseUint(...),
    15  // so we only can test to 62 bits.
    16  const maxUintBitsToTest = 62
    17  
    18  func TestUnmarshalWithFullNameNotStruct(t *testing.T) {
    19  	var s map[string]interface{}
    20  	content := []byte(`{"name":"xiaoming"}`)
    21  	err := UnmarshalJsonBytes(content, &s)
    22  	assert.Equal(t, errValueNotStruct, err)
    23  }
    24  
    25  func TestUnmarshalWithoutTagName(t *testing.T) {
    26  	type inner struct {
    27  		Optional bool `key:",optional"`
    28  	}
    29  	m := map[string]interface{}{
    30  		"Optional": true,
    31  	}
    32  
    33  	var in inner
    34  	assert.Nil(t, UnmarshalKey(m, &in))
    35  	assert.True(t, in.Optional)
    36  }
    37  
    38  func TestUnmarshalBool(t *testing.T) {
    39  	type inner struct {
    40  		True           bool `key:"yes"`
    41  		False          bool `key:"no"`
    42  		TrueFromOne    bool `key:"yesone,string"`
    43  		FalseFromZero  bool `key:"nozero,string"`
    44  		TrueFromTrue   bool `key:"yestrue,string"`
    45  		FalseFromFalse bool `key:"nofalse,string"`
    46  		DefaultTrue    bool `key:"defaulttrue,default=1"`
    47  		Optional       bool `key:"optional,optional"`
    48  	}
    49  	m := map[string]interface{}{
    50  		"yes":     true,
    51  		"no":      false,
    52  		"yesone":  "1",
    53  		"nozero":  "0",
    54  		"yestrue": "true",
    55  		"nofalse": "false",
    56  	}
    57  
    58  	var in inner
    59  	ast := assert.New(t)
    60  	ast.Nil(UnmarshalKey(m, &in))
    61  	ast.True(in.True)
    62  	ast.False(in.False)
    63  	ast.True(in.TrueFromOne)
    64  	ast.False(in.FalseFromZero)
    65  	ast.True(in.TrueFromTrue)
    66  	ast.False(in.FalseFromFalse)
    67  	ast.True(in.DefaultTrue)
    68  }
    69  
    70  func TestUnmarshalDuration(t *testing.T) {
    71  	type inner struct {
    72  		Duration     time.Duration `key:"duration"`
    73  		LessDuration time.Duration `key:"less"`
    74  		MoreDuration time.Duration `key:"more"`
    75  	}
    76  	m := map[string]interface{}{
    77  		"duration": "5s",
    78  		"less":     "100ms",
    79  		"more":     "24h",
    80  	}
    81  	var in inner
    82  	assert.Nil(t, UnmarshalKey(m, &in))
    83  	assert.Equal(t, time.Second*5, in.Duration)
    84  	assert.Equal(t, time.Millisecond*100, in.LessDuration)
    85  	assert.Equal(t, time.Hour*24, in.MoreDuration)
    86  }
    87  
    88  func TestUnmarshalDurationDefault(t *testing.T) {
    89  	type inner struct {
    90  		Int      int           `key:"int"`
    91  		Duration time.Duration `key:"duration,default=5s"`
    92  	}
    93  	m := map[string]interface{}{
    94  		"int": 5,
    95  	}
    96  	var in inner
    97  	assert.Nil(t, UnmarshalKey(m, &in))
    98  	assert.Equal(t, 5, in.Int)
    99  	assert.Equal(t, time.Second*5, in.Duration)
   100  }
   101  
   102  func TestUnmarshalDurationPtr(t *testing.T) {
   103  	type inner struct {
   104  		Duration *time.Duration `key:"duration"`
   105  	}
   106  	m := map[string]interface{}{
   107  		"duration": "5s",
   108  	}
   109  	var in inner
   110  	assert.Nil(t, UnmarshalKey(m, &in))
   111  	assert.Equal(t, time.Second*5, *in.Duration)
   112  }
   113  
   114  func TestUnmarshalDurationPtrDefault(t *testing.T) {
   115  	type inner struct {
   116  		Int      int            `key:"int"`
   117  		Value    *int           `key:",default=5"`
   118  		Duration *time.Duration `key:"duration,default=5s"`
   119  	}
   120  	m := map[string]interface{}{
   121  		"int": 5,
   122  	}
   123  	var in inner
   124  	assert.Nil(t, UnmarshalKey(m, &in))
   125  	assert.Equal(t, 5, in.Int)
   126  	assert.Equal(t, 5, *in.Value)
   127  	assert.Equal(t, time.Second*5, *in.Duration)
   128  }
   129  
   130  func TestUnmarshalInt(t *testing.T) {
   131  	type inner struct {
   132  		Int          int   `key:"int"`
   133  		IntFromStr   int   `key:"intstr,string"`
   134  		Int8         int8  `key:"int8"`
   135  		Int8FromStr  int8  `key:"int8str,string"`
   136  		Int16        int16 `key:"int16"`
   137  		Int16FromStr int16 `key:"int16str,string"`
   138  		Int32        int32 `key:"int32"`
   139  		Int32FromStr int32 `key:"int32str,string"`
   140  		Int64        int64 `key:"int64"`
   141  		Int64FromStr int64 `key:"int64str,string"`
   142  		DefaultInt   int64 `key:"defaultint,default=11"`
   143  		Optional     int   `key:"optional,optional"`
   144  	}
   145  	m := map[string]interface{}{
   146  		"int":      1,
   147  		"intstr":   "2",
   148  		"int8":     int8(3),
   149  		"int8str":  "4",
   150  		"int16":    int16(5),
   151  		"int16str": "6",
   152  		"int32":    int32(7),
   153  		"int32str": "8",
   154  		"int64":    int64(9),
   155  		"int64str": "10",
   156  	}
   157  
   158  	var in inner
   159  	ast := assert.New(t)
   160  	ast.Nil(UnmarshalKey(m, &in))
   161  	ast.Equal(1, in.Int)
   162  	ast.Equal(2, in.IntFromStr)
   163  	ast.Equal(int8(3), in.Int8)
   164  	ast.Equal(int8(4), in.Int8FromStr)
   165  	ast.Equal(int16(5), in.Int16)
   166  	ast.Equal(int16(6), in.Int16FromStr)
   167  	ast.Equal(int32(7), in.Int32)
   168  	ast.Equal(int32(8), in.Int32FromStr)
   169  	ast.Equal(int64(9), in.Int64)
   170  	ast.Equal(int64(10), in.Int64FromStr)
   171  	ast.Equal(int64(11), in.DefaultInt)
   172  }
   173  
   174  func TestUnmarshalIntPtr(t *testing.T) {
   175  	type inner struct {
   176  		Int *int `key:"int"`
   177  	}
   178  	m := map[string]interface{}{
   179  		"int": 1,
   180  	}
   181  
   182  	var in inner
   183  	assert.Nil(t, UnmarshalKey(m, &in))
   184  	assert.NotNil(t, in.Int)
   185  	assert.Equal(t, 1, *in.Int)
   186  }
   187  
   188  func TestUnmarshalIntWithDefault(t *testing.T) {
   189  	type inner struct {
   190  		Int int `key:"int,default=5"`
   191  	}
   192  	m := map[string]interface{}{
   193  		"int": 1,
   194  	}
   195  
   196  	var in inner
   197  	assert.Nil(t, UnmarshalKey(m, &in))
   198  	assert.Equal(t, 1, in.Int)
   199  }
   200  
   201  func TestUnmarshalBoolSliceWithDefault(t *testing.T) {
   202  	type inner struct {
   203  		Bools []bool `key:"bools,default=[true,false]"`
   204  	}
   205  
   206  	var in inner
   207  	assert.Nil(t, UnmarshalKey(nil, &in))
   208  	assert.ElementsMatch(t, []bool{true, false}, in.Bools)
   209  }
   210  
   211  func TestUnmarshalIntSliceWithDefault(t *testing.T) {
   212  	type inner struct {
   213  		Ints []int `key:"ints,default=[1,2,3]"`
   214  	}
   215  
   216  	var in inner
   217  	assert.Nil(t, UnmarshalKey(nil, &in))
   218  	assert.ElementsMatch(t, []int{1, 2, 3}, in.Ints)
   219  }
   220  
   221  func TestUnmarshalIntSliceWithDefaultHasSpaces(t *testing.T) {
   222  	type inner struct {
   223  		Ints []int `key:"ints,default=[1, 2, 3]"`
   224  	}
   225  
   226  	var in inner
   227  	assert.Nil(t, UnmarshalKey(nil, &in))
   228  	assert.ElementsMatch(t, []int{1, 2, 3}, in.Ints)
   229  }
   230  
   231  func TestUnmarshalFloatSliceWithDefault(t *testing.T) {
   232  	type inner struct {
   233  		Floats []float32 `key:"floats,default=[1.1,2.2,3.3]"`
   234  	}
   235  
   236  	var in inner
   237  	assert.Nil(t, UnmarshalKey(nil, &in))
   238  	assert.ElementsMatch(t, []float32{1.1, 2.2, 3.3}, in.Floats)
   239  }
   240  
   241  func TestUnmarshalStringSliceWithDefault(t *testing.T) {
   242  	type inner struct {
   243  		Strs []string `key:"strs,default=[foo,bar,woo]"`
   244  	}
   245  
   246  	var in inner
   247  	assert.Nil(t, UnmarshalKey(nil, &in))
   248  	assert.ElementsMatch(t, []string{"foo", "bar", "woo"}, in.Strs)
   249  }
   250  
   251  func TestUnmarshalStringSliceWithDefaultHasSpaces(t *testing.T) {
   252  	type inner struct {
   253  		Strs []string `key:"strs,default=[foo, bar, woo]"`
   254  	}
   255  
   256  	var in inner
   257  	assert.Nil(t, UnmarshalKey(nil, &in))
   258  	assert.ElementsMatch(t, []string{"foo", "bar", "woo"}, in.Strs)
   259  }
   260  
   261  func TestUnmarshalUint(t *testing.T) {
   262  	type inner struct {
   263  		Uint          uint   `key:"uint"`
   264  		UintFromStr   uint   `key:"uintstr,string"`
   265  		Uint8         uint8  `key:"uint8"`
   266  		Uint8FromStr  uint8  `key:"uint8str,string"`
   267  		Uint16        uint16 `key:"uint16"`
   268  		Uint16FromStr uint16 `key:"uint16str,string"`
   269  		Uint32        uint32 `key:"uint32"`
   270  		Uint32FromStr uint32 `key:"uint32str,string"`
   271  		Uint64        uint64 `key:"uint64"`
   272  		Uint64FromStr uint64 `key:"uint64str,string"`
   273  		DefaultUint   uint   `key:"defaultuint,default=11"`
   274  		Optional      uint   `key:"optional,optional"`
   275  	}
   276  	m := map[string]interface{}{
   277  		"uint":      uint(1),
   278  		"uintstr":   "2",
   279  		"uint8":     uint8(3),
   280  		"uint8str":  "4",
   281  		"uint16":    uint16(5),
   282  		"uint16str": "6",
   283  		"uint32":    uint32(7),
   284  		"uint32str": "8",
   285  		"uint64":    uint64(9),
   286  		"uint64str": "10",
   287  	}
   288  
   289  	var in inner
   290  	ast := assert.New(t)
   291  	ast.Nil(UnmarshalKey(m, &in))
   292  	ast.Equal(uint(1), in.Uint)
   293  	ast.Equal(uint(2), in.UintFromStr)
   294  	ast.Equal(uint8(3), in.Uint8)
   295  	ast.Equal(uint8(4), in.Uint8FromStr)
   296  	ast.Equal(uint16(5), in.Uint16)
   297  	ast.Equal(uint16(6), in.Uint16FromStr)
   298  	ast.Equal(uint32(7), in.Uint32)
   299  	ast.Equal(uint32(8), in.Uint32FromStr)
   300  	ast.Equal(uint64(9), in.Uint64)
   301  	ast.Equal(uint64(10), in.Uint64FromStr)
   302  	ast.Equal(uint(11), in.DefaultUint)
   303  }
   304  
   305  func TestUnmarshalFloat(t *testing.T) {
   306  	type inner struct {
   307  		Float32      float32 `key:"float32"`
   308  		Float32Str   float32 `key:"float32str,string"`
   309  		Float64      float64 `key:"float64"`
   310  		Float64Str   float64 `key:"float64str,string"`
   311  		DefaultFloat float32 `key:"defaultfloat,default=5.5"`
   312  		Optional     float32 `key:",optional"`
   313  	}
   314  	m := map[string]interface{}{
   315  		"float32":    float32(1.5),
   316  		"float32str": "2.5",
   317  		"float64":    float64(3.5),
   318  		"float64str": "4.5",
   319  	}
   320  
   321  	var in inner
   322  	ast := assert.New(t)
   323  	ast.Nil(UnmarshalKey(m, &in))
   324  	ast.Equal(float32(1.5), in.Float32)
   325  	ast.Equal(float32(2.5), in.Float32Str)
   326  	ast.Equal(3.5, in.Float64)
   327  	ast.Equal(4.5, in.Float64Str)
   328  	ast.Equal(float32(5.5), in.DefaultFloat)
   329  }
   330  
   331  func TestUnmarshalInt64Slice(t *testing.T) {
   332  	var v struct {
   333  		Ages []int64 `key:"ages"`
   334  	}
   335  	m := map[string]interface{}{
   336  		"ages": []int64{1, 2},
   337  	}
   338  
   339  	ast := assert.New(t)
   340  	ast.Nil(UnmarshalKey(m, &v))
   341  	ast.ElementsMatch([]int64{1, 2}, v.Ages)
   342  }
   343  
   344  func TestUnmarshalIntSlice(t *testing.T) {
   345  	var v struct {
   346  		Ages []int `key:"ages"`
   347  	}
   348  	m := map[string]interface{}{
   349  		"ages": []int{1, 2},
   350  	}
   351  
   352  	ast := assert.New(t)
   353  	ast.Nil(UnmarshalKey(m, &v))
   354  	ast.ElementsMatch([]int{1, 2}, v.Ages)
   355  }
   356  
   357  func TestUnmarshalString(t *testing.T) {
   358  	type inner struct {
   359  		Name              string `key:"name"`
   360  		NameStr           string `key:"namestr,string"`
   361  		NotPresent        string `key:",optional"`
   362  		NotPresentWithTag string `key:"notpresent,optional"`
   363  		DefaultString     string `key:"defaultstring,default=hello"`
   364  		Optional          string `key:",optional"`
   365  	}
   366  	m := map[string]interface{}{
   367  		"name":    "kevin",
   368  		"namestr": "namewithstring",
   369  	}
   370  
   371  	var in inner
   372  	ast := assert.New(t)
   373  	ast.Nil(UnmarshalKey(m, &in))
   374  	ast.Equal("kevin", in.Name)
   375  	ast.Equal("namewithstring", in.NameStr)
   376  	ast.Empty(in.NotPresent)
   377  	ast.Empty(in.NotPresentWithTag)
   378  	ast.Equal("hello", in.DefaultString)
   379  }
   380  
   381  func TestUnmarshalStringWithMissing(t *testing.T) {
   382  	type inner struct {
   383  		Name string `key:"name"`
   384  	}
   385  	m := map[string]interface{}{}
   386  
   387  	var in inner
   388  	assert.NotNil(t, UnmarshalKey(m, &in))
   389  }
   390  
   391  func TestUnmarshalStringSliceFromString(t *testing.T) {
   392  	var v struct {
   393  		Names []string `key:"names"`
   394  	}
   395  	m := map[string]interface{}{
   396  		"names": `["first", "second"]`,
   397  	}
   398  
   399  	ast := assert.New(t)
   400  	ast.Nil(UnmarshalKey(m, &v))
   401  	ast.Equal(2, len(v.Names))
   402  	ast.Equal("first", v.Names[0])
   403  	ast.Equal("second", v.Names[1])
   404  }
   405  
   406  func TestUnmarshalIntSliceFromString(t *testing.T) {
   407  	var v struct {
   408  		Values []int `key:"values"`
   409  	}
   410  	m := map[string]interface{}{
   411  		"values": `[1, 2]`,
   412  	}
   413  
   414  	ast := assert.New(t)
   415  	ast.Nil(UnmarshalKey(m, &v))
   416  	ast.Equal(2, len(v.Values))
   417  	ast.Equal(1, v.Values[0])
   418  	ast.Equal(2, v.Values[1])
   419  }
   420  
   421  func TestUnmarshalStruct(t *testing.T) {
   422  	type address struct {
   423  		City          string `key:"city"`
   424  		ZipCode       int    `key:"zipcode,string"`
   425  		DefaultString string `key:"defaultstring,default=hello"`
   426  		Optional      string `key:",optional"`
   427  	}
   428  	type inner struct {
   429  		Name    string  `key:"name"`
   430  		Address address `key:"address"`
   431  	}
   432  	m := map[string]interface{}{
   433  		"name": "kevin",
   434  		"address": map[string]interface{}{
   435  			"city":    "shanghai",
   436  			"zipcode": "200000",
   437  		},
   438  	}
   439  
   440  	var in inner
   441  	ast := assert.New(t)
   442  	ast.Nil(UnmarshalKey(m, &in))
   443  	ast.Equal("kevin", in.Name)
   444  	ast.Equal("shanghai", in.Address.City)
   445  	ast.Equal(200000, in.Address.ZipCode)
   446  	ast.Equal("hello", in.Address.DefaultString)
   447  }
   448  
   449  func TestUnmarshalStructOptionalDepends(t *testing.T) {
   450  	type address struct {
   451  		City            string `key:"city"`
   452  		Optional        string `key:",optional"`
   453  		OptionalDepends string `key:",optional=Optional"`
   454  	}
   455  	type inner struct {
   456  		Name    string  `key:"name"`
   457  		Address address `key:"address"`
   458  	}
   459  
   460  	tests := []struct {
   461  		input map[string]string
   462  		pass  bool
   463  	}{
   464  		{
   465  			pass: true,
   466  		},
   467  		{
   468  			input: map[string]string{
   469  				"OptionalDepends": "b",
   470  			},
   471  			pass: false,
   472  		},
   473  		{
   474  			input: map[string]string{
   475  				"Optional": "a",
   476  			},
   477  			pass: false,
   478  		},
   479  		{
   480  			input: map[string]string{
   481  				"Optional":        "a",
   482  				"OptionalDepends": "b",
   483  			},
   484  			pass: true,
   485  		},
   486  	}
   487  
   488  	for _, test := range tests {
   489  		t.Run(stringx.Rand(), func(t *testing.T) {
   490  			m := map[string]interface{}{
   491  				"name": "kevin",
   492  				"address": map[string]interface{}{
   493  					"city": "shanghai",
   494  				},
   495  			}
   496  			for k, v := range test.input {
   497  				m["address"].(map[string]interface{})[k] = v
   498  			}
   499  
   500  			var in inner
   501  			ast := assert.New(t)
   502  			if test.pass {
   503  				ast.Nil(UnmarshalKey(m, &in))
   504  				ast.Equal("kevin", in.Name)
   505  				ast.Equal("shanghai", in.Address.City)
   506  				ast.Equal(test.input["Optional"], in.Address.Optional)
   507  				ast.Equal(test.input["OptionalDepends"], in.Address.OptionalDepends)
   508  			} else {
   509  				ast.NotNil(UnmarshalKey(m, &in))
   510  			}
   511  		})
   512  	}
   513  }
   514  
   515  func TestUnmarshalStructOptionalDependsNot(t *testing.T) {
   516  	type address struct {
   517  		City            string `key:"city"`
   518  		Optional        string `key:",optional"`
   519  		OptionalDepends string `key:",optional=!Optional"`
   520  	}
   521  	type inner struct {
   522  		Name    string  `key:"name"`
   523  		Address address `key:"address"`
   524  	}
   525  
   526  	tests := []struct {
   527  		input map[string]string
   528  		pass  bool
   529  	}{
   530  		{
   531  			input: map[string]string{},
   532  			pass:  false,
   533  		},
   534  		{
   535  			input: map[string]string{
   536  				"Optional":        "a",
   537  				"OptionalDepends": "b",
   538  			},
   539  			pass: false,
   540  		},
   541  		{
   542  			input: map[string]string{
   543  				"Optional": "a",
   544  			},
   545  			pass: true,
   546  		},
   547  		{
   548  			input: map[string]string{
   549  				"OptionalDepends": "b",
   550  			},
   551  			pass: true,
   552  		},
   553  	}
   554  
   555  	for _, test := range tests {
   556  		t.Run(stringx.Rand(), func(t *testing.T) {
   557  			m := map[string]interface{}{
   558  				"name": "kevin",
   559  				"address": map[string]interface{}{
   560  					"city": "shanghai",
   561  				},
   562  			}
   563  			for k, v := range test.input {
   564  				m["address"].(map[string]interface{})[k] = v
   565  			}
   566  
   567  			var in inner
   568  			ast := assert.New(t)
   569  			if test.pass {
   570  				ast.Nil(UnmarshalKey(m, &in))
   571  				ast.Equal("kevin", in.Name)
   572  				ast.Equal("shanghai", in.Address.City)
   573  				ast.Equal(test.input["Optional"], in.Address.Optional)
   574  				ast.Equal(test.input["OptionalDepends"], in.Address.OptionalDepends)
   575  			} else {
   576  				ast.NotNil(UnmarshalKey(m, &in))
   577  			}
   578  		})
   579  	}
   580  }
   581  
   582  func TestUnmarshalStructOptionalDependsNotErrorDetails(t *testing.T) {
   583  	type address struct {
   584  		Optional        string `key:",optional"`
   585  		OptionalDepends string `key:",optional=!Optional"`
   586  	}
   587  	type inner struct {
   588  		Name    string  `key:"name"`
   589  		Address address `key:"address"`
   590  	}
   591  
   592  	m := map[string]interface{}{
   593  		"name": "kevin",
   594  	}
   595  
   596  	var in inner
   597  	err := UnmarshalKey(m, &in)
   598  	assert.NotNil(t, err)
   599  }
   600  
   601  func TestUnmarshalStructOptionalDependsNotNested(t *testing.T) {
   602  	type address struct {
   603  		Optional        string `key:",optional"`
   604  		OptionalDepends string `key:",optional=!Optional"`
   605  	}
   606  	type combo struct {
   607  		Name    string  `key:"name,optional"`
   608  		Address address `key:"address"`
   609  	}
   610  	type inner struct {
   611  		Name  string `key:"name"`
   612  		Combo combo  `key:"combo"`
   613  	}
   614  
   615  	m := map[string]interface{}{
   616  		"name": "kevin",
   617  	}
   618  
   619  	var in inner
   620  	err := UnmarshalKey(m, &in)
   621  	assert.NotNil(t, err)
   622  }
   623  
   624  func TestUnmarshalStructOptionalNestedDifferentKey(t *testing.T) {
   625  	type address struct {
   626  		Optional        string `dkey:",optional"`
   627  		OptionalDepends string `key:",optional"`
   628  	}
   629  	type combo struct {
   630  		Name    string  `key:"name,optional"`
   631  		Address address `key:"address"`
   632  	}
   633  	type inner struct {
   634  		Name  string `key:"name"`
   635  		Combo combo  `key:"combo"`
   636  	}
   637  
   638  	m := map[string]interface{}{
   639  		"name": "kevin",
   640  	}
   641  
   642  	var in inner
   643  	assert.NotNil(t, UnmarshalKey(m, &in))
   644  }
   645  
   646  func TestUnmarshalStructOptionalDependsNotEnoughValue(t *testing.T) {
   647  	type address struct {
   648  		Optional        string `key:",optional"`
   649  		OptionalDepends string `key:",optional=!"`
   650  	}
   651  	type inner struct {
   652  		Name    string  `key:"name"`
   653  		Address address `key:"address"`
   654  	}
   655  
   656  	m := map[string]interface{}{
   657  		"name":    "kevin",
   658  		"address": map[string]interface{}{},
   659  	}
   660  
   661  	var in inner
   662  	err := UnmarshalKey(m, &in)
   663  	assert.NotNil(t, err)
   664  }
   665  
   666  func TestUnmarshalAnonymousStructOptionalDepends(t *testing.T) {
   667  	type AnonAddress struct {
   668  		City            string `key:"city"`
   669  		Optional        string `key:",optional"`
   670  		OptionalDepends string `key:",optional=Optional"`
   671  	}
   672  	type inner struct {
   673  		Name string `key:"name"`
   674  		AnonAddress
   675  	}
   676  
   677  	tests := []struct {
   678  		input map[string]string
   679  		pass  bool
   680  	}{
   681  		{
   682  			pass: true,
   683  		},
   684  		{
   685  			input: map[string]string{
   686  				"OptionalDepends": "b",
   687  			},
   688  			pass: false,
   689  		},
   690  		{
   691  			input: map[string]string{
   692  				"Optional": "a",
   693  			},
   694  			pass: false,
   695  		},
   696  		{
   697  			input: map[string]string{
   698  				"Optional":        "a",
   699  				"OptionalDepends": "b",
   700  			},
   701  			pass: true,
   702  		},
   703  	}
   704  
   705  	for _, test := range tests {
   706  		t.Run(stringx.Rand(), func(t *testing.T) {
   707  			m := map[string]interface{}{
   708  				"name": "kevin",
   709  				"city": "shanghai",
   710  			}
   711  			for k, v := range test.input {
   712  				m[k] = v
   713  			}
   714  
   715  			var in inner
   716  			ast := assert.New(t)
   717  			if test.pass {
   718  				ast.Nil(UnmarshalKey(m, &in))
   719  				ast.Equal("kevin", in.Name)
   720  				ast.Equal("shanghai", in.City)
   721  				ast.Equal(test.input["Optional"], in.Optional)
   722  				ast.Equal(test.input["OptionalDepends"], in.OptionalDepends)
   723  			} else {
   724  				ast.NotNil(UnmarshalKey(m, &in))
   725  			}
   726  		})
   727  	}
   728  }
   729  
   730  func TestUnmarshalStructPtr(t *testing.T) {
   731  	type address struct {
   732  		City          string `key:"city"`
   733  		ZipCode       int    `key:"zipcode,string"`
   734  		DefaultString string `key:"defaultstring,default=hello"`
   735  		Optional      string `key:",optional"`
   736  	}
   737  	type inner struct {
   738  		Name    string   `key:"name"`
   739  		Address *address `key:"address"`
   740  	}
   741  	m := map[string]interface{}{
   742  		"name": "kevin",
   743  		"address": map[string]interface{}{
   744  			"city":    "shanghai",
   745  			"zipcode": "200000",
   746  		},
   747  	}
   748  
   749  	var in inner
   750  	ast := assert.New(t)
   751  	ast.Nil(UnmarshalKey(m, &in))
   752  	ast.Equal("kevin", in.Name)
   753  	ast.Equal("shanghai", in.Address.City)
   754  	ast.Equal(200000, in.Address.ZipCode)
   755  	ast.Equal("hello", in.Address.DefaultString)
   756  }
   757  
   758  func TestUnmarshalWithStringIgnored(t *testing.T) {
   759  	type inner struct {
   760  		True    bool    `key:"yes"`
   761  		False   bool    `key:"no"`
   762  		Int     int     `key:"int"`
   763  		Int8    int8    `key:"int8"`
   764  		Int16   int16   `key:"int16"`
   765  		Int32   int32   `key:"int32"`
   766  		Int64   int64   `key:"int64"`
   767  		Uint    uint    `key:"uint"`
   768  		Uint8   uint8   `key:"uint8"`
   769  		Uint16  uint16  `key:"uint16"`
   770  		Uint32  uint32  `key:"uint32"`
   771  		Uint64  uint64  `key:"uint64"`
   772  		Float32 float32 `key:"float32"`
   773  		Float64 float64 `key:"float64"`
   774  	}
   775  	m := map[string]interface{}{
   776  		"yes":     "1",
   777  		"no":      "0",
   778  		"int":     "1",
   779  		"int8":    "3",
   780  		"int16":   "5",
   781  		"int32":   "7",
   782  		"int64":   "9",
   783  		"uint":    "1",
   784  		"uint8":   "3",
   785  		"uint16":  "5",
   786  		"uint32":  "7",
   787  		"uint64":  "9",
   788  		"float32": "1.5",
   789  		"float64": "3.5",
   790  	}
   791  
   792  	var in inner
   793  	um := NewUnmarshaler("key", WithStringValues())
   794  	ast := assert.New(t)
   795  	ast.Nil(um.Unmarshal(m, &in))
   796  	ast.True(in.True)
   797  	ast.False(in.False)
   798  	ast.Equal(1, in.Int)
   799  	ast.Equal(int8(3), in.Int8)
   800  	ast.Equal(int16(5), in.Int16)
   801  	ast.Equal(int32(7), in.Int32)
   802  	ast.Equal(int64(9), in.Int64)
   803  	ast.Equal(uint(1), in.Uint)
   804  	ast.Equal(uint8(3), in.Uint8)
   805  	ast.Equal(uint16(5), in.Uint16)
   806  	ast.Equal(uint32(7), in.Uint32)
   807  	ast.Equal(uint64(9), in.Uint64)
   808  	ast.Equal(float32(1.5), in.Float32)
   809  	ast.Equal(3.5, in.Float64)
   810  }
   811  
   812  func TestUnmarshalJsonNumberInt64(t *testing.T) {
   813  	for i := 0; i <= maxUintBitsToTest; i++ {
   814  		var intValue int64 = 1 << uint(i)
   815  		strValue := strconv.FormatInt(intValue, 10)
   816  		number := json.Number(strValue)
   817  		m := map[string]interface{}{
   818  			"ID": number,
   819  		}
   820  		var v struct {
   821  			ID int64
   822  		}
   823  		assert.Nil(t, UnmarshalKey(m, &v))
   824  		assert.Equal(t, intValue, v.ID)
   825  	}
   826  }
   827  
   828  func TestUnmarshalJsonNumberUint64(t *testing.T) {
   829  	for i := 0; i <= maxUintBitsToTest; i++ {
   830  		var intValue uint64 = 1 << uint(i)
   831  		strValue := strconv.FormatUint(intValue, 10)
   832  		number := json.Number(strValue)
   833  		m := map[string]interface{}{
   834  			"ID": number,
   835  		}
   836  		var v struct {
   837  			ID uint64
   838  		}
   839  		assert.Nil(t, UnmarshalKey(m, &v))
   840  		assert.Equal(t, intValue, v.ID)
   841  	}
   842  }
   843  
   844  func TestUnmarshalJsonNumberUint64Ptr(t *testing.T) {
   845  	for i := 0; i <= maxUintBitsToTest; i++ {
   846  		var intValue uint64 = 1 << uint(i)
   847  		strValue := strconv.FormatUint(intValue, 10)
   848  		number := json.Number(strValue)
   849  		m := map[string]interface{}{
   850  			"ID": number,
   851  		}
   852  		var v struct {
   853  			ID *uint64
   854  		}
   855  		ast := assert.New(t)
   856  		ast.Nil(UnmarshalKey(m, &v))
   857  		ast.NotNil(v.ID)
   858  		ast.Equal(intValue, *v.ID)
   859  	}
   860  }
   861  
   862  func TestUnmarshalMapOfInt(t *testing.T) {
   863  	m := map[string]interface{}{
   864  		"Ids": map[string]bool{"first": true},
   865  	}
   866  	var v struct {
   867  		Ids map[string]bool
   868  	}
   869  	assert.Nil(t, UnmarshalKey(m, &v))
   870  	assert.True(t, v.Ids["first"])
   871  }
   872  
   873  func TestUnmarshalMapOfStructError(t *testing.T) {
   874  	m := map[string]interface{}{
   875  		"Ids": map[string]interface{}{"first": "second"},
   876  	}
   877  	var v struct {
   878  		Ids map[string]struct {
   879  			Name string
   880  		}
   881  	}
   882  	assert.NotNil(t, UnmarshalKey(m, &v))
   883  }
   884  
   885  func TestUnmarshalSlice(t *testing.T) {
   886  	m := map[string]interface{}{
   887  		"Ids": []interface{}{"first", "second"},
   888  	}
   889  	var v struct {
   890  		Ids []string
   891  	}
   892  	ast := assert.New(t)
   893  	ast.Nil(UnmarshalKey(m, &v))
   894  	ast.Equal(2, len(v.Ids))
   895  	ast.Equal("first", v.Ids[0])
   896  	ast.Equal("second", v.Ids[1])
   897  }
   898  
   899  func TestUnmarshalSliceOfStruct(t *testing.T) {
   900  	m := map[string]interface{}{
   901  		"Ids": []map[string]interface{}{
   902  			{
   903  				"First":  1,
   904  				"Second": 2,
   905  			},
   906  		},
   907  	}
   908  	var v struct {
   909  		Ids []struct {
   910  			First  int
   911  			Second int
   912  		}
   913  	}
   914  	ast := assert.New(t)
   915  	ast.Nil(UnmarshalKey(m, &v))
   916  	ast.Equal(1, len(v.Ids))
   917  	ast.Equal(1, v.Ids[0].First)
   918  	ast.Equal(2, v.Ids[0].Second)
   919  }
   920  
   921  func TestUnmarshalWithStringOptionsCorrect(t *testing.T) {
   922  	type inner struct {
   923  		Value   string `key:"value,options=first|second"`
   924  		Foo     string `key:"foo,options=[bar,baz]"`
   925  		Correct string `key:"correct,options=1|2"`
   926  	}
   927  	m := map[string]interface{}{
   928  		"value":   "first",
   929  		"foo":     "bar",
   930  		"correct": "2",
   931  	}
   932  
   933  	var in inner
   934  	ast := assert.New(t)
   935  	ast.Nil(UnmarshalKey(m, &in))
   936  	ast.Equal("first", in.Value)
   937  	ast.Equal("bar", in.Foo)
   938  	ast.Equal("2", in.Correct)
   939  }
   940  
   941  func TestUnmarshalStringOptionsWithStringOptionsNotString(t *testing.T) {
   942  	type inner struct {
   943  		Value   string `key:"value,options=first|second"`
   944  		Correct string `key:"correct,options=1|2"`
   945  	}
   946  	m := map[string]interface{}{
   947  		"value":   "first",
   948  		"correct": 2,
   949  	}
   950  
   951  	var in inner
   952  	unmarshaler := NewUnmarshaler(defaultKeyName, WithStringValues())
   953  	ast := assert.New(t)
   954  	ast.NotNil(unmarshaler.Unmarshal(m, &in))
   955  }
   956  
   957  func TestUnmarshalStringOptionsWithStringOptions(t *testing.T) {
   958  	type inner struct {
   959  		Value   string `key:"value,options=first|second"`
   960  		Correct string `key:"correct,options=1|2"`
   961  	}
   962  	m := map[string]interface{}{
   963  		"value":   "first",
   964  		"correct": "2",
   965  	}
   966  
   967  	var in inner
   968  	unmarshaler := NewUnmarshaler(defaultKeyName, WithStringValues())
   969  	ast := assert.New(t)
   970  	ast.Nil(unmarshaler.Unmarshal(m, &in))
   971  	ast.Equal("first", in.Value)
   972  	ast.Equal("2", in.Correct)
   973  }
   974  
   975  func TestUnmarshalStringOptionsWithStringOptionsPtr(t *testing.T) {
   976  	type inner struct {
   977  		Value   *string `key:"value,options=first|second"`
   978  		Correct *int    `key:"correct,options=1|2"`
   979  	}
   980  	m := map[string]interface{}{
   981  		"value":   "first",
   982  		"correct": "2",
   983  	}
   984  
   985  	var in inner
   986  	unmarshaler := NewUnmarshaler(defaultKeyName, WithStringValues())
   987  	ast := assert.New(t)
   988  	ast.Nil(unmarshaler.Unmarshal(m, &in))
   989  	ast.True(*in.Value == "first")
   990  	ast.True(*in.Correct == 2)
   991  }
   992  
   993  func TestUnmarshalStringOptionsWithStringOptionsIncorrect(t *testing.T) {
   994  	type inner struct {
   995  		Value   string `key:"value,options=first|second"`
   996  		Correct string `key:"correct,options=1|2"`
   997  	}
   998  	m := map[string]interface{}{
   999  		"value":   "third",
  1000  		"correct": "2",
  1001  	}
  1002  
  1003  	var in inner
  1004  	unmarshaler := NewUnmarshaler(defaultKeyName, WithStringValues())
  1005  	ast := assert.New(t)
  1006  	ast.NotNil(unmarshaler.Unmarshal(m, &in))
  1007  }
  1008  
  1009  func TestUnmarshalStringOptionsWithStringOptionsIncorrectGrouped(t *testing.T) {
  1010  	type inner struct {
  1011  		Value   string `key:"value,options=[first,second]"`
  1012  		Correct string `key:"correct,options=1|2"`
  1013  	}
  1014  	m := map[string]interface{}{
  1015  		"value":   "third",
  1016  		"correct": "2",
  1017  	}
  1018  
  1019  	var in inner
  1020  	unmarshaler := NewUnmarshaler(defaultKeyName, WithStringValues())
  1021  	ast := assert.New(t)
  1022  	ast.NotNil(unmarshaler.Unmarshal(m, &in))
  1023  }
  1024  
  1025  func TestUnmarshalWithStringOptionsIncorrect(t *testing.T) {
  1026  	type inner struct {
  1027  		Value     string `key:"value,options=first|second"`
  1028  		Incorrect string `key:"incorrect,options=1|2"`
  1029  	}
  1030  	m := map[string]interface{}{
  1031  		"value":     "first",
  1032  		"incorrect": "3",
  1033  	}
  1034  
  1035  	var in inner
  1036  	assert.NotNil(t, UnmarshalKey(m, &in))
  1037  }
  1038  
  1039  func TestUnmarshalWithIntOptionsCorrect(t *testing.T) {
  1040  	type inner struct {
  1041  		Value  string `key:"value,options=first|second"`
  1042  		Number int    `key:"number,options=1|2"`
  1043  	}
  1044  	m := map[string]interface{}{
  1045  		"value":  "first",
  1046  		"number": 2,
  1047  	}
  1048  
  1049  	var in inner
  1050  	ast := assert.New(t)
  1051  	ast.Nil(UnmarshalKey(m, &in))
  1052  	ast.Equal("first", in.Value)
  1053  	ast.Equal(2, in.Number)
  1054  }
  1055  
  1056  func TestUnmarshalWithIntOptionsCorrectPtr(t *testing.T) {
  1057  	type inner struct {
  1058  		Value  *string `key:"value,options=first|second"`
  1059  		Number *int    `key:"number,options=1|2"`
  1060  	}
  1061  	m := map[string]interface{}{
  1062  		"value":  "first",
  1063  		"number": 2,
  1064  	}
  1065  
  1066  	var in inner
  1067  	ast := assert.New(t)
  1068  	ast.Nil(UnmarshalKey(m, &in))
  1069  	ast.True(*in.Value == "first")
  1070  	ast.True(*in.Number == 2)
  1071  }
  1072  
  1073  func TestUnmarshalWithIntOptionsIncorrect(t *testing.T) {
  1074  	type inner struct {
  1075  		Value     string `key:"value,options=first|second"`
  1076  		Incorrect int    `key:"incorrect,options=1|2"`
  1077  	}
  1078  	m := map[string]interface{}{
  1079  		"value":     "first",
  1080  		"incorrect": 3,
  1081  	}
  1082  
  1083  	var in inner
  1084  	assert.NotNil(t, UnmarshalKey(m, &in))
  1085  }
  1086  
  1087  func TestUnmarshalWithUintOptionsCorrect(t *testing.T) {
  1088  	type inner struct {
  1089  		Value  string `key:"value,options=first|second"`
  1090  		Number uint   `key:"number,options=1|2"`
  1091  	}
  1092  	m := map[string]interface{}{
  1093  		"value":  "first",
  1094  		"number": uint(2),
  1095  	}
  1096  
  1097  	var in inner
  1098  	ast := assert.New(t)
  1099  	ast.Nil(UnmarshalKey(m, &in))
  1100  	ast.Equal("first", in.Value)
  1101  	ast.Equal(uint(2), in.Number)
  1102  }
  1103  
  1104  func TestUnmarshalWithUintOptionsIncorrect(t *testing.T) {
  1105  	type inner struct {
  1106  		Value     string `key:"value,options=first|second"`
  1107  		Incorrect uint   `key:"incorrect,options=1|2"`
  1108  	}
  1109  	m := map[string]interface{}{
  1110  		"value":     "first",
  1111  		"incorrect": uint(3),
  1112  	}
  1113  
  1114  	var in inner
  1115  	assert.NotNil(t, UnmarshalKey(m, &in))
  1116  }
  1117  
  1118  func TestUnmarshalWithOptionsAndDefault(t *testing.T) {
  1119  	type inner struct {
  1120  		Value string `key:"value,options=first|second|third,default=second"`
  1121  	}
  1122  	m := map[string]interface{}{}
  1123  
  1124  	var in inner
  1125  	assert.Nil(t, UnmarshalKey(m, &in))
  1126  	assert.Equal(t, "second", in.Value)
  1127  }
  1128  
  1129  func TestUnmarshalWithOptionsAndSet(t *testing.T) {
  1130  	type inner struct {
  1131  		Value string `key:"value,options=first|second|third,default=second"`
  1132  	}
  1133  	m := map[string]interface{}{
  1134  		"value": "first",
  1135  	}
  1136  
  1137  	var in inner
  1138  	assert.Nil(t, UnmarshalKey(m, &in))
  1139  	assert.Equal(t, "first", in.Value)
  1140  }
  1141  
  1142  func TestUnmarshalNestedKey(t *testing.T) {
  1143  	var c struct {
  1144  		ID int `json:"Persons.first.ID"`
  1145  	}
  1146  	m := map[string]interface{}{
  1147  		"Persons": map[string]interface{}{
  1148  			"first": map[string]interface{}{
  1149  				"ID": 1,
  1150  			},
  1151  		},
  1152  	}
  1153  
  1154  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &c))
  1155  	assert.Equal(t, 1, c.ID)
  1156  }
  1157  
  1158  func TestUnmarhsalNestedKeyArray(t *testing.T) {
  1159  	var c struct {
  1160  		First []struct {
  1161  			ID int
  1162  		} `json:"Persons.first"`
  1163  	}
  1164  	m := map[string]interface{}{
  1165  		"Persons": map[string]interface{}{
  1166  			"first": []map[string]interface{}{
  1167  				{"ID": 1},
  1168  				{"ID": 2},
  1169  			},
  1170  		},
  1171  	}
  1172  
  1173  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &c))
  1174  	assert.Equal(t, 2, len(c.First))
  1175  	assert.Equal(t, 1, c.First[0].ID)
  1176  }
  1177  
  1178  func TestUnmarshalAnonymousOptionalRequiredProvided(t *testing.T) {
  1179  	type (
  1180  		Foo struct {
  1181  			Value string `json:"v"`
  1182  		}
  1183  
  1184  		Bar struct {
  1185  			Foo `json:",optional"`
  1186  		}
  1187  	)
  1188  	m := map[string]interface{}{
  1189  		"v": "anything",
  1190  	}
  1191  
  1192  	var b Bar
  1193  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1194  	assert.Equal(t, "anything", b.Value)
  1195  }
  1196  
  1197  func TestUnmarshalAnonymousOptionalRequiredMissed(t *testing.T) {
  1198  	type (
  1199  		Foo struct {
  1200  			Value string `json:"v"`
  1201  		}
  1202  
  1203  		Bar struct {
  1204  			Foo `json:",optional"`
  1205  		}
  1206  	)
  1207  	m := map[string]interface{}{}
  1208  
  1209  	var b Bar
  1210  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1211  	assert.True(t, len(b.Value) == 0)
  1212  }
  1213  
  1214  func TestUnmarshalAnonymousOptionalOptionalProvided(t *testing.T) {
  1215  	type (
  1216  		Foo struct {
  1217  			Value string `json:"v,optional"`
  1218  		}
  1219  
  1220  		Bar struct {
  1221  			Foo `json:",optional"`
  1222  		}
  1223  	)
  1224  	m := map[string]interface{}{
  1225  		"v": "anything",
  1226  	}
  1227  
  1228  	var b Bar
  1229  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1230  	assert.Equal(t, "anything", b.Value)
  1231  }
  1232  
  1233  func TestUnmarshalAnonymousOptionalOptionalMissed(t *testing.T) {
  1234  	type (
  1235  		Foo struct {
  1236  			Value string `json:"v,optional"`
  1237  		}
  1238  
  1239  		Bar struct {
  1240  			Foo `json:",optional"`
  1241  		}
  1242  	)
  1243  	m := map[string]interface{}{}
  1244  
  1245  	var b Bar
  1246  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1247  	assert.True(t, len(b.Value) == 0)
  1248  }
  1249  
  1250  func TestUnmarshalAnonymousOptionalRequiredBothProvided(t *testing.T) {
  1251  	type (
  1252  		Foo struct {
  1253  			Name  string `json:"n"`
  1254  			Value string `json:"v"`
  1255  		}
  1256  
  1257  		Bar struct {
  1258  			Foo `json:",optional"`
  1259  		}
  1260  	)
  1261  	m := map[string]interface{}{
  1262  		"n": "kevin",
  1263  		"v": "anything",
  1264  	}
  1265  
  1266  	var b Bar
  1267  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1268  	assert.Equal(t, "kevin", b.Name)
  1269  	assert.Equal(t, "anything", b.Value)
  1270  }
  1271  
  1272  func TestUnmarshalAnonymousOptionalRequiredOneProvidedOneMissed(t *testing.T) {
  1273  	type (
  1274  		Foo struct {
  1275  			Name  string `json:"n"`
  1276  			Value string `json:"v"`
  1277  		}
  1278  
  1279  		Bar struct {
  1280  			Foo `json:",optional"`
  1281  		}
  1282  	)
  1283  	m := map[string]interface{}{
  1284  		"v": "anything",
  1285  	}
  1286  
  1287  	var b Bar
  1288  	assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1289  }
  1290  
  1291  func TestUnmarshalAnonymousOptionalRequiredBothMissed(t *testing.T) {
  1292  	type (
  1293  		Foo struct {
  1294  			Name  string `json:"n"`
  1295  			Value string `json:"v"`
  1296  		}
  1297  
  1298  		Bar struct {
  1299  			Foo `json:",optional"`
  1300  		}
  1301  	)
  1302  	m := map[string]interface{}{}
  1303  
  1304  	var b Bar
  1305  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1306  	assert.True(t, len(b.Name) == 0)
  1307  	assert.True(t, len(b.Value) == 0)
  1308  }
  1309  
  1310  func TestUnmarshalAnonymousOptionalOneRequiredOneOptionalBothProvided(t *testing.T) {
  1311  	type (
  1312  		Foo struct {
  1313  			Name  string `json:"n,optional"`
  1314  			Value string `json:"v"`
  1315  		}
  1316  
  1317  		Bar struct {
  1318  			Foo `json:",optional"`
  1319  		}
  1320  	)
  1321  	m := map[string]interface{}{
  1322  		"n": "kevin",
  1323  		"v": "anything",
  1324  	}
  1325  
  1326  	var b Bar
  1327  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1328  	assert.Equal(t, "kevin", b.Name)
  1329  	assert.Equal(t, "anything", b.Value)
  1330  }
  1331  
  1332  func TestUnmarshalAnonymousOptionalOneRequiredOneOptionalBothMissed(t *testing.T) {
  1333  	type (
  1334  		Foo struct {
  1335  			Name  string `json:"n,optional"`
  1336  			Value string `json:"v"`
  1337  		}
  1338  
  1339  		Bar struct {
  1340  			Foo `json:",optional"`
  1341  		}
  1342  	)
  1343  	m := map[string]interface{}{}
  1344  
  1345  	var b Bar
  1346  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1347  	assert.True(t, len(b.Name) == 0)
  1348  	assert.True(t, len(b.Value) == 0)
  1349  }
  1350  
  1351  func TestUnmarshalAnonymousOptionalOneRequiredOneOptionalRequiredProvidedOptionalMissed(t *testing.T) {
  1352  	type (
  1353  		Foo struct {
  1354  			Name  string `json:"n,optional"`
  1355  			Value string `json:"v"`
  1356  		}
  1357  
  1358  		Bar struct {
  1359  			Foo `json:",optional"`
  1360  		}
  1361  	)
  1362  	m := map[string]interface{}{
  1363  		"v": "anything",
  1364  	}
  1365  
  1366  	var b Bar
  1367  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1368  	assert.True(t, len(b.Name) == 0)
  1369  	assert.Equal(t, "anything", b.Value)
  1370  }
  1371  
  1372  func TestUnmarshalAnonymousOptionalOneRequiredOneOptionalRequiredMissedOptionalProvided(t *testing.T) {
  1373  	type (
  1374  		Foo struct {
  1375  			Name  string `json:"n,optional"`
  1376  			Value string `json:"v"`
  1377  		}
  1378  
  1379  		Bar struct {
  1380  			Foo `json:",optional"`
  1381  		}
  1382  	)
  1383  	m := map[string]interface{}{
  1384  		"n": "anything",
  1385  	}
  1386  
  1387  	var b Bar
  1388  	assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1389  }
  1390  
  1391  func TestUnmarshalAnonymousOptionalBothOptionalBothProvided(t *testing.T) {
  1392  	type (
  1393  		Foo struct {
  1394  			Name  string `json:"n,optional"`
  1395  			Value string `json:"v,optional"`
  1396  		}
  1397  
  1398  		Bar struct {
  1399  			Foo `json:",optional"`
  1400  		}
  1401  	)
  1402  	m := map[string]interface{}{
  1403  		"n": "kevin",
  1404  		"v": "anything",
  1405  	}
  1406  
  1407  	var b Bar
  1408  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1409  	assert.Equal(t, "kevin", b.Name)
  1410  	assert.Equal(t, "anything", b.Value)
  1411  }
  1412  
  1413  func TestUnmarshalAnonymousOptionalBothOptionalOneProvidedOneMissed(t *testing.T) {
  1414  	type (
  1415  		Foo struct {
  1416  			Name  string `json:"n,optional"`
  1417  			Value string `json:"v,optional"`
  1418  		}
  1419  
  1420  		Bar struct {
  1421  			Foo `json:",optional"`
  1422  		}
  1423  	)
  1424  	m := map[string]interface{}{
  1425  		"v": "anything",
  1426  	}
  1427  
  1428  	var b Bar
  1429  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1430  	assert.True(t, len(b.Name) == 0)
  1431  	assert.Equal(t, "anything", b.Value)
  1432  }
  1433  
  1434  func TestUnmarshalAnonymousOptionalBothOptionalBothMissed(t *testing.T) {
  1435  	type (
  1436  		Foo struct {
  1437  			Name  string `json:"n,optional"`
  1438  			Value string `json:"v,optional"`
  1439  		}
  1440  
  1441  		Bar struct {
  1442  			Foo `json:",optional"`
  1443  		}
  1444  	)
  1445  	m := map[string]interface{}{}
  1446  
  1447  	var b Bar
  1448  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1449  	assert.True(t, len(b.Name) == 0)
  1450  	assert.True(t, len(b.Value) == 0)
  1451  }
  1452  
  1453  func TestUnmarshalAnonymousRequiredProvided(t *testing.T) {
  1454  	type (
  1455  		Foo struct {
  1456  			Value string `json:"v"`
  1457  		}
  1458  
  1459  		Bar struct {
  1460  			Foo
  1461  		}
  1462  	)
  1463  	m := map[string]interface{}{
  1464  		"v": "anything",
  1465  	}
  1466  
  1467  	var b Bar
  1468  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1469  	assert.Equal(t, "anything", b.Value)
  1470  }
  1471  
  1472  func TestUnmarshalAnonymousRequiredMissed(t *testing.T) {
  1473  	type (
  1474  		Foo struct {
  1475  			Value string `json:"v"`
  1476  		}
  1477  
  1478  		Bar struct {
  1479  			Foo
  1480  		}
  1481  	)
  1482  	m := map[string]interface{}{}
  1483  
  1484  	var b Bar
  1485  	assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1486  }
  1487  
  1488  func TestUnmarshalAnonymousOptionalProvided(t *testing.T) {
  1489  	type (
  1490  		Foo struct {
  1491  			Value string `json:"v,optional"`
  1492  		}
  1493  
  1494  		Bar struct {
  1495  			Foo
  1496  		}
  1497  	)
  1498  	m := map[string]interface{}{
  1499  		"v": "anything",
  1500  	}
  1501  
  1502  	var b Bar
  1503  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1504  	assert.Equal(t, "anything", b.Value)
  1505  }
  1506  
  1507  func TestUnmarshalAnonymousOptionalMissed(t *testing.T) {
  1508  	type (
  1509  		Foo struct {
  1510  			Value string `json:"v,optional"`
  1511  		}
  1512  
  1513  		Bar struct {
  1514  			Foo
  1515  		}
  1516  	)
  1517  	m := map[string]interface{}{}
  1518  
  1519  	var b Bar
  1520  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1521  	assert.True(t, len(b.Value) == 0)
  1522  }
  1523  
  1524  func TestUnmarshalAnonymousRequiredBothProvided(t *testing.T) {
  1525  	type (
  1526  		Foo struct {
  1527  			Name  string `json:"n"`
  1528  			Value string `json:"v"`
  1529  		}
  1530  
  1531  		Bar struct {
  1532  			Foo
  1533  		}
  1534  	)
  1535  	m := map[string]interface{}{
  1536  		"n": "kevin",
  1537  		"v": "anything",
  1538  	}
  1539  
  1540  	var b Bar
  1541  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1542  	assert.Equal(t, "kevin", b.Name)
  1543  	assert.Equal(t, "anything", b.Value)
  1544  }
  1545  
  1546  func TestUnmarshalAnonymousRequiredOneProvidedOneMissed(t *testing.T) {
  1547  	type (
  1548  		Foo struct {
  1549  			Name  string `json:"n"`
  1550  			Value string `json:"v"`
  1551  		}
  1552  
  1553  		Bar struct {
  1554  			Foo
  1555  		}
  1556  	)
  1557  	m := map[string]interface{}{
  1558  		"v": "anything",
  1559  	}
  1560  
  1561  	var b Bar
  1562  	assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1563  }
  1564  
  1565  func TestUnmarshalAnonymousRequiredBothMissed(t *testing.T) {
  1566  	type (
  1567  		Foo struct {
  1568  			Name  string `json:"n"`
  1569  			Value string `json:"v"`
  1570  		}
  1571  
  1572  		Bar struct {
  1573  			Foo
  1574  		}
  1575  	)
  1576  	m := map[string]interface{}{
  1577  		"v": "anything",
  1578  	}
  1579  
  1580  	var b Bar
  1581  	assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1582  }
  1583  
  1584  func TestUnmarshalAnonymousOneRequiredOneOptionalBothProvided(t *testing.T) {
  1585  	type (
  1586  		Foo struct {
  1587  			Name  string `json:"n,optional"`
  1588  			Value string `json:"v"`
  1589  		}
  1590  
  1591  		Bar struct {
  1592  			Foo
  1593  		}
  1594  	)
  1595  	m := map[string]interface{}{
  1596  		"n": "kevin",
  1597  		"v": "anything",
  1598  	}
  1599  
  1600  	var b Bar
  1601  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1602  	assert.Equal(t, "kevin", b.Name)
  1603  	assert.Equal(t, "anything", b.Value)
  1604  }
  1605  
  1606  func TestUnmarshalAnonymousOneRequiredOneOptionalBothMissed(t *testing.T) {
  1607  	type (
  1608  		Foo struct {
  1609  			Name  string `json:"n,optional"`
  1610  			Value string `json:"v"`
  1611  		}
  1612  
  1613  		Bar struct {
  1614  			Foo
  1615  		}
  1616  	)
  1617  	m := map[string]interface{}{}
  1618  
  1619  	var b Bar
  1620  	assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1621  }
  1622  
  1623  func TestUnmarshalAnonymousOneRequiredOneOptionalRequiredProvidedOptionalMissed(t *testing.T) {
  1624  	type (
  1625  		Foo struct {
  1626  			Name  string `json:"n,optional"`
  1627  			Value string `json:"v"`
  1628  		}
  1629  
  1630  		Bar struct {
  1631  			Foo
  1632  		}
  1633  	)
  1634  	m := map[string]interface{}{
  1635  		"v": "anything",
  1636  	}
  1637  
  1638  	var b Bar
  1639  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1640  	assert.True(t, len(b.Name) == 0)
  1641  	assert.Equal(t, "anything", b.Value)
  1642  }
  1643  
  1644  func TestUnmarshalAnonymousOneRequiredOneOptionalRequiredMissedOptionalProvided(t *testing.T) {
  1645  	type (
  1646  		Foo struct {
  1647  			Name  string `json:"n,optional"`
  1648  			Value string `json:"v"`
  1649  		}
  1650  
  1651  		Bar struct {
  1652  			Foo
  1653  		}
  1654  	)
  1655  	m := map[string]interface{}{
  1656  		"n": "anything",
  1657  	}
  1658  
  1659  	var b Bar
  1660  	assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1661  }
  1662  
  1663  func TestUnmarshalAnonymousBothOptionalBothProvided(t *testing.T) {
  1664  	type (
  1665  		Foo struct {
  1666  			Name  string `json:"n,optional"`
  1667  			Value string `json:"v,optional"`
  1668  		}
  1669  
  1670  		Bar struct {
  1671  			Foo
  1672  		}
  1673  	)
  1674  	m := map[string]interface{}{
  1675  		"n": "kevin",
  1676  		"v": "anything",
  1677  	}
  1678  
  1679  	var b Bar
  1680  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1681  	assert.Equal(t, "kevin", b.Name)
  1682  	assert.Equal(t, "anything", b.Value)
  1683  }
  1684  
  1685  func TestUnmarshalAnonymousBothOptionalOneProvidedOneMissed(t *testing.T) {
  1686  	type (
  1687  		Foo struct {
  1688  			Name  string `json:"n,optional"`
  1689  			Value string `json:"v,optional"`
  1690  		}
  1691  
  1692  		Bar struct {
  1693  			Foo
  1694  		}
  1695  	)
  1696  	m := map[string]interface{}{
  1697  		"v": "anything",
  1698  	}
  1699  
  1700  	var b Bar
  1701  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1702  	assert.True(t, len(b.Name) == 0)
  1703  	assert.Equal(t, "anything", b.Value)
  1704  }
  1705  
  1706  func TestUnmarshalAnonymousBothOptionalBothMissed(t *testing.T) {
  1707  	type (
  1708  		Foo struct {
  1709  			Name  string `json:"n,optional"`
  1710  			Value string `json:"v,optional"`
  1711  		}
  1712  
  1713  		Bar struct {
  1714  			Foo
  1715  		}
  1716  	)
  1717  	m := map[string]interface{}{}
  1718  
  1719  	var b Bar
  1720  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1721  	assert.True(t, len(b.Name) == 0)
  1722  	assert.True(t, len(b.Value) == 0)
  1723  }
  1724  
  1725  func TestUnmarshalAnonymousWrappedToMuch(t *testing.T) {
  1726  	type (
  1727  		Foo struct {
  1728  			Name  string `json:"n"`
  1729  			Value string `json:"v"`
  1730  		}
  1731  
  1732  		Bar struct {
  1733  			Foo
  1734  		}
  1735  	)
  1736  	m := map[string]interface{}{
  1737  		"Foo": map[string]interface{}{
  1738  			"n": "name",
  1739  			"v": "anything",
  1740  		},
  1741  	}
  1742  
  1743  	var b Bar
  1744  	assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1745  }
  1746  
  1747  func TestUnmarshalWrappedObject(t *testing.T) {
  1748  	type (
  1749  		Foo struct {
  1750  			Value string `json:"v"`
  1751  		}
  1752  
  1753  		Bar struct {
  1754  			Inner Foo
  1755  		}
  1756  	)
  1757  	m := map[string]interface{}{
  1758  		"Inner": map[string]interface{}{
  1759  			"v": "anything",
  1760  		},
  1761  	}
  1762  
  1763  	var b Bar
  1764  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1765  	assert.Equal(t, "anything", b.Inner.Value)
  1766  }
  1767  
  1768  func TestUnmarshalWrappedObjectOptional(t *testing.T) {
  1769  	type (
  1770  		Foo struct {
  1771  			Hosts []string
  1772  			Key   string
  1773  		}
  1774  
  1775  		Bar struct {
  1776  			Inner Foo `json:",optional"`
  1777  			Name  string
  1778  		}
  1779  	)
  1780  	m := map[string]interface{}{
  1781  		"Name": "anything",
  1782  	}
  1783  
  1784  	var b Bar
  1785  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1786  	assert.Equal(t, "anything", b.Name)
  1787  }
  1788  
  1789  func TestUnmarshalWrappedObjectOptionalFilled(t *testing.T) {
  1790  	type (
  1791  		Foo struct {
  1792  			Hosts []string
  1793  			Key   string
  1794  		}
  1795  
  1796  		Bar struct {
  1797  			Inner Foo `json:",optional"`
  1798  			Name  string
  1799  		}
  1800  	)
  1801  	hosts := []string{"1", "2"}
  1802  	m := map[string]interface{}{
  1803  		"Inner": map[string]interface{}{
  1804  			"Hosts": hosts,
  1805  			"Key":   "key",
  1806  		},
  1807  		"Name": "anything",
  1808  	}
  1809  
  1810  	var b Bar
  1811  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1812  	assert.EqualValues(t, hosts, b.Inner.Hosts)
  1813  	assert.Equal(t, "key", b.Inner.Key)
  1814  	assert.Equal(t, "anything", b.Name)
  1815  }
  1816  
  1817  func TestUnmarshalWrappedNamedObjectOptional(t *testing.T) {
  1818  	type (
  1819  		Foo struct {
  1820  			Host string
  1821  			Key  string
  1822  		}
  1823  
  1824  		Bar struct {
  1825  			Inner Foo `json:",optional"`
  1826  			Name  string
  1827  		}
  1828  	)
  1829  	m := map[string]interface{}{
  1830  		"Inner": map[string]interface{}{
  1831  			"Host": "thehost",
  1832  			"Key":  "thekey",
  1833  		},
  1834  		"Name": "anything",
  1835  	}
  1836  
  1837  	var b Bar
  1838  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1839  	assert.Equal(t, "thehost", b.Inner.Host)
  1840  	assert.Equal(t, "thekey", b.Inner.Key)
  1841  	assert.Equal(t, "anything", b.Name)
  1842  }
  1843  
  1844  func TestUnmarshalWrappedObjectNamedPtr(t *testing.T) {
  1845  	type (
  1846  		Foo struct {
  1847  			Value string `json:"v"`
  1848  		}
  1849  
  1850  		Bar struct {
  1851  			Inner *Foo `json:"foo,optional"`
  1852  		}
  1853  	)
  1854  	m := map[string]interface{}{
  1855  		"foo": map[string]interface{}{
  1856  			"v": "anything",
  1857  		},
  1858  	}
  1859  
  1860  	var b Bar
  1861  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1862  	assert.Equal(t, "anything", b.Inner.Value)
  1863  }
  1864  
  1865  func TestUnmarshalWrappedObjectPtr(t *testing.T) {
  1866  	type (
  1867  		Foo struct {
  1868  			Value string `json:"v"`
  1869  		}
  1870  
  1871  		Bar struct {
  1872  			Inner *Foo
  1873  		}
  1874  	)
  1875  	m := map[string]interface{}{
  1876  		"Inner": map[string]interface{}{
  1877  			"v": "anything",
  1878  		},
  1879  	}
  1880  
  1881  	var b Bar
  1882  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &b))
  1883  	assert.Equal(t, "anything", b.Inner.Value)
  1884  }
  1885  
  1886  func TestUnmarshalInt2String(t *testing.T) {
  1887  	type inner struct {
  1888  		Int string `key:"int"`
  1889  	}
  1890  	m := map[string]interface{}{
  1891  		"int": 123,
  1892  	}
  1893  
  1894  	var in inner
  1895  	assert.NotNil(t, UnmarshalKey(m, &in))
  1896  }
  1897  
  1898  func TestUnmarshalZeroValues(t *testing.T) {
  1899  	type inner struct {
  1900  		False  bool   `key:"no"`
  1901  		Int    int    `key:"int"`
  1902  		String string `key:"string"`
  1903  	}
  1904  	m := map[string]interface{}{
  1905  		"no":     false,
  1906  		"int":    0,
  1907  		"string": "",
  1908  	}
  1909  
  1910  	var in inner
  1911  	ast := assert.New(t)
  1912  	ast.Nil(UnmarshalKey(m, &in))
  1913  	ast.False(in.False)
  1914  	ast.Equal(0, in.Int)
  1915  	ast.Equal("", in.String)
  1916  }
  1917  
  1918  func TestUnmarshalUsingDifferentKeys(t *testing.T) {
  1919  	type inner struct {
  1920  		False  bool   `key:"no"`
  1921  		Int    int    `key:"int"`
  1922  		String string `bson:"string"`
  1923  	}
  1924  	m := map[string]interface{}{
  1925  		"no":     false,
  1926  		"int":    9,
  1927  		"string": "value",
  1928  	}
  1929  
  1930  	var in inner
  1931  	ast := assert.New(t)
  1932  	ast.Nil(UnmarshalKey(m, &in))
  1933  	ast.False(in.False)
  1934  	ast.Equal(9, in.Int)
  1935  	ast.True(len(in.String) == 0)
  1936  }
  1937  
  1938  func TestUnmarshalNumberRangeInt(t *testing.T) {
  1939  	type inner struct {
  1940  		Value1  int    `key:"value1,range=[1:]"`
  1941  		Value2  int8   `key:"value2,range=[1:5]"`
  1942  		Value3  int16  `key:"value3,range=[1:5]"`
  1943  		Value4  int32  `key:"value4,range=[1:5]"`
  1944  		Value5  int64  `key:"value5,range=[1:5]"`
  1945  		Value6  uint   `key:"value6,range=[:5]"`
  1946  		Value8  uint8  `key:"value8,range=[1:5],string"`
  1947  		Value9  uint16 `key:"value9,range=[1:5],string"`
  1948  		Value10 uint32 `key:"value10,range=[1:5],string"`
  1949  		Value11 uint64 `key:"value11,range=[1:5],string"`
  1950  	}
  1951  	m := map[string]interface{}{
  1952  		"value1":  10,
  1953  		"value2":  int8(1),
  1954  		"value3":  int16(2),
  1955  		"value4":  int32(4),
  1956  		"value5":  int64(5),
  1957  		"value6":  uint(0),
  1958  		"value8":  "1",
  1959  		"value9":  "2",
  1960  		"value10": "4",
  1961  		"value11": "5",
  1962  	}
  1963  
  1964  	var in inner
  1965  	ast := assert.New(t)
  1966  	ast.Nil(UnmarshalKey(m, &in))
  1967  	ast.Equal(10, in.Value1)
  1968  	ast.Equal(int8(1), in.Value2)
  1969  	ast.Equal(int16(2), in.Value3)
  1970  	ast.Equal(int32(4), in.Value4)
  1971  	ast.Equal(int64(5), in.Value5)
  1972  	ast.Equal(uint(0), in.Value6)
  1973  	ast.Equal(uint8(1), in.Value8)
  1974  	ast.Equal(uint16(2), in.Value9)
  1975  	ast.Equal(uint32(4), in.Value10)
  1976  	ast.Equal(uint64(5), in.Value11)
  1977  }
  1978  
  1979  func TestUnmarshalNumberRangeJsonNumber(t *testing.T) {
  1980  	type inner struct {
  1981  		Value3 uint   `key:"value3,range=(1:5]"`
  1982  		Value4 uint8  `key:"value4,range=(1:5]"`
  1983  		Value5 uint16 `key:"value5,range=(1:5]"`
  1984  	}
  1985  	m := map[string]interface{}{
  1986  		"value3": json.Number("2"),
  1987  		"value4": json.Number("4"),
  1988  		"value5": json.Number("5"),
  1989  	}
  1990  
  1991  	var in inner
  1992  	ast := assert.New(t)
  1993  	ast.Nil(UnmarshalKey(m, &in))
  1994  	ast.Equal(uint(2), in.Value3)
  1995  	ast.Equal(uint8(4), in.Value4)
  1996  	ast.Equal(uint16(5), in.Value5)
  1997  
  1998  	type inner1 struct {
  1999  		Value int `key:"value,range=(1:5]"`
  2000  	}
  2001  	m = map[string]interface{}{
  2002  		"value": json.Number("a"),
  2003  	}
  2004  
  2005  	var in1 inner1
  2006  	ast.NotNil(UnmarshalKey(m, &in1))
  2007  }
  2008  
  2009  func TestUnmarshalNumberRangeIntLeftExclude(t *testing.T) {
  2010  	type inner struct {
  2011  		Value3  uint   `key:"value3,range=(1:5]"`
  2012  		Value4  uint32 `key:"value4,default=4,range=(1:5]"`
  2013  		Value5  uint64 `key:"value5,range=(1:5]"`
  2014  		Value9  int    `key:"value9,range=(1:5],string"`
  2015  		Value10 int    `key:"value10,range=(1:5],string"`
  2016  		Value11 int    `key:"value11,range=(1:5],string"`
  2017  	}
  2018  	m := map[string]interface{}{
  2019  		"value3":  uint(2),
  2020  		"value4":  uint32(4),
  2021  		"value5":  uint64(5),
  2022  		"value9":  "2",
  2023  		"value10": "4",
  2024  		"value11": "5",
  2025  	}
  2026  
  2027  	var in inner
  2028  	ast := assert.New(t)
  2029  	ast.Nil(UnmarshalKey(m, &in))
  2030  	ast.Equal(uint(2), in.Value3)
  2031  	ast.Equal(uint32(4), in.Value4)
  2032  	ast.Equal(uint64(5), in.Value5)
  2033  	ast.Equal(2, in.Value9)
  2034  	ast.Equal(4, in.Value10)
  2035  	ast.Equal(5, in.Value11)
  2036  }
  2037  
  2038  func TestUnmarshalNumberRangeIntRightExclude(t *testing.T) {
  2039  	type inner struct {
  2040  		Value2  uint   `key:"value2,range=[1:5)"`
  2041  		Value3  uint8  `key:"value3,range=[1:5)"`
  2042  		Value4  uint16 `key:"value4,range=[1:5)"`
  2043  		Value8  int    `key:"value8,range=[1:5),string"`
  2044  		Value9  int    `key:"value9,range=[1:5),string"`
  2045  		Value10 int    `key:"value10,range=[1:5),string"`
  2046  	}
  2047  	m := map[string]interface{}{
  2048  		"value2":  uint(1),
  2049  		"value3":  uint8(2),
  2050  		"value4":  uint16(4),
  2051  		"value8":  "1",
  2052  		"value9":  "2",
  2053  		"value10": "4",
  2054  	}
  2055  
  2056  	var in inner
  2057  	ast := assert.New(t)
  2058  	ast.Nil(UnmarshalKey(m, &in))
  2059  	ast.Equal(uint(1), in.Value2)
  2060  	ast.Equal(uint8(2), in.Value3)
  2061  	ast.Equal(uint16(4), in.Value4)
  2062  	ast.Equal(1, in.Value8)
  2063  	ast.Equal(2, in.Value9)
  2064  	ast.Equal(4, in.Value10)
  2065  }
  2066  
  2067  func TestUnmarshalNumberRangeIntExclude(t *testing.T) {
  2068  	type inner struct {
  2069  		Value3  int `key:"value3,range=(1:5)"`
  2070  		Value4  int `key:"value4,range=(1:5)"`
  2071  		Value9  int `key:"value9,range=(1:5),string"`
  2072  		Value10 int `key:"value10,range=(1:5),string"`
  2073  	}
  2074  	m := map[string]interface{}{
  2075  		"value3":  2,
  2076  		"value4":  4,
  2077  		"value9":  "2",
  2078  		"value10": "4",
  2079  	}
  2080  
  2081  	var in inner
  2082  	ast := assert.New(t)
  2083  	ast.Nil(UnmarshalKey(m, &in))
  2084  	ast.Equal(2, in.Value3)
  2085  	ast.Equal(4, in.Value4)
  2086  	ast.Equal(2, in.Value9)
  2087  	ast.Equal(4, in.Value10)
  2088  }
  2089  
  2090  func TestUnmarshalNumberRangeIntOutOfRange(t *testing.T) {
  2091  	type inner1 struct {
  2092  		Value int64 `key:"value,default=3,range=(1:5)"`
  2093  	}
  2094  
  2095  	var in1 inner1
  2096  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2097  		"value": int64(1),
  2098  	}, &in1))
  2099  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2100  		"value": int64(0),
  2101  	}, &in1))
  2102  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2103  		"value": int64(5),
  2104  	}, &in1))
  2105  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2106  		"value": json.Number("6"),
  2107  	}, &in1))
  2108  
  2109  	type inner2 struct {
  2110  		Value int64 `key:"value,optional,range=[1:5)"`
  2111  	}
  2112  
  2113  	var in2 inner2
  2114  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2115  		"value": int64(0),
  2116  	}, &in2))
  2117  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2118  		"value": int64(5),
  2119  	}, &in2))
  2120  
  2121  	type inner3 struct {
  2122  		Value int64 `key:"value,range=(1:5]"`
  2123  	}
  2124  
  2125  	var in3 inner3
  2126  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2127  		"value": int64(1),
  2128  	}, &in3))
  2129  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2130  		"value": int64(6),
  2131  	}, &in3))
  2132  
  2133  	type inner4 struct {
  2134  		Value int64 `key:"value,range=[1:5]"`
  2135  	}
  2136  
  2137  	var in4 inner4
  2138  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2139  		"value": int64(0),
  2140  	}, &in4))
  2141  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2142  		"value": int64(6),
  2143  	}, &in4))
  2144  }
  2145  
  2146  func TestUnmarshalNumberRangeFloat(t *testing.T) {
  2147  	type inner struct {
  2148  		Value2  float32 `key:"value2,range=[1:5]"`
  2149  		Value3  float32 `key:"value3,range=[1:5]"`
  2150  		Value4  float64 `key:"value4,range=[1:5]"`
  2151  		Value5  float64 `key:"value5,range=[1:5]"`
  2152  		Value8  float64 `key:"value8,range=[1:5],string"`
  2153  		Value9  float64 `key:"value9,range=[1:5],string"`
  2154  		Value10 float64 `key:"value10,range=[1:5],string"`
  2155  		Value11 float64 `key:"value11,range=[1:5],string"`
  2156  	}
  2157  	m := map[string]interface{}{
  2158  		"value2":  float32(1),
  2159  		"value3":  float32(2),
  2160  		"value4":  float64(4),
  2161  		"value5":  float64(5),
  2162  		"value8":  "1",
  2163  		"value9":  "2",
  2164  		"value10": "4",
  2165  		"value11": "5",
  2166  	}
  2167  
  2168  	var in inner
  2169  	ast := assert.New(t)
  2170  	ast.Nil(UnmarshalKey(m, &in))
  2171  	ast.Equal(float32(1), in.Value2)
  2172  	ast.Equal(float32(2), in.Value3)
  2173  	ast.Equal(float64(4), in.Value4)
  2174  	ast.Equal(float64(5), in.Value5)
  2175  	ast.Equal(float64(1), in.Value8)
  2176  	ast.Equal(float64(2), in.Value9)
  2177  	ast.Equal(float64(4), in.Value10)
  2178  	ast.Equal(float64(5), in.Value11)
  2179  }
  2180  
  2181  func TestUnmarshalNumberRangeFloatLeftExclude(t *testing.T) {
  2182  	type inner struct {
  2183  		Value3  float64 `key:"value3,range=(1:5]"`
  2184  		Value4  float64 `key:"value4,range=(1:5]"`
  2185  		Value5  float64 `key:"value5,range=(1:5]"`
  2186  		Value9  float64 `key:"value9,range=(1:5],string"`
  2187  		Value10 float64 `key:"value10,range=(1:5],string"`
  2188  		Value11 float64 `key:"value11,range=(1:5],string"`
  2189  	}
  2190  	m := map[string]interface{}{
  2191  		"value3":  float64(2),
  2192  		"value4":  float64(4),
  2193  		"value5":  float64(5),
  2194  		"value9":  "2",
  2195  		"value10": "4",
  2196  		"value11": "5",
  2197  	}
  2198  
  2199  	var in inner
  2200  	ast := assert.New(t)
  2201  	ast.Nil(UnmarshalKey(m, &in))
  2202  	ast.Equal(float64(2), in.Value3)
  2203  	ast.Equal(float64(4), in.Value4)
  2204  	ast.Equal(float64(5), in.Value5)
  2205  	ast.Equal(float64(2), in.Value9)
  2206  	ast.Equal(float64(4), in.Value10)
  2207  	ast.Equal(float64(5), in.Value11)
  2208  }
  2209  
  2210  func TestUnmarshalNumberRangeFloatRightExclude(t *testing.T) {
  2211  	type inner struct {
  2212  		Value2  float64 `key:"value2,range=[1:5)"`
  2213  		Value3  float64 `key:"value3,range=[1:5)"`
  2214  		Value4  float64 `key:"value4,range=[1:5)"`
  2215  		Value8  float64 `key:"value8,range=[1:5),string"`
  2216  		Value9  float64 `key:"value9,range=[1:5),string"`
  2217  		Value10 float64 `key:"value10,range=[1:5),string"`
  2218  	}
  2219  	m := map[string]interface{}{
  2220  		"value2":  float64(1),
  2221  		"value3":  float64(2),
  2222  		"value4":  float64(4),
  2223  		"value8":  "1",
  2224  		"value9":  "2",
  2225  		"value10": "4",
  2226  	}
  2227  
  2228  	var in inner
  2229  	ast := assert.New(t)
  2230  	ast.Nil(UnmarshalKey(m, &in))
  2231  	ast.Equal(float64(1), in.Value2)
  2232  	ast.Equal(float64(2), in.Value3)
  2233  	ast.Equal(float64(4), in.Value4)
  2234  	ast.Equal(float64(1), in.Value8)
  2235  	ast.Equal(float64(2), in.Value9)
  2236  	ast.Equal(float64(4), in.Value10)
  2237  }
  2238  
  2239  func TestUnmarshalNumberRangeFloatExclude(t *testing.T) {
  2240  	type inner struct {
  2241  		Value3  float64 `key:"value3,range=(1:5)"`
  2242  		Value4  float64 `key:"value4,range=(1:5)"`
  2243  		Value9  float64 `key:"value9,range=(1:5),string"`
  2244  		Value10 float64 `key:"value10,range=(1:5),string"`
  2245  	}
  2246  	m := map[string]interface{}{
  2247  		"value3":  float64(2),
  2248  		"value4":  float64(4),
  2249  		"value9":  "2",
  2250  		"value10": "4",
  2251  	}
  2252  
  2253  	var in inner
  2254  	ast := assert.New(t)
  2255  	ast.Nil(UnmarshalKey(m, &in))
  2256  	ast.Equal(float64(2), in.Value3)
  2257  	ast.Equal(float64(4), in.Value4)
  2258  	ast.Equal(float64(2), in.Value9)
  2259  	ast.Equal(float64(4), in.Value10)
  2260  }
  2261  
  2262  func TestUnmarshalNumberRangeFloatOutOfRange(t *testing.T) {
  2263  	type inner1 struct {
  2264  		Value float64 `key:"value,range=(1:5)"`
  2265  	}
  2266  
  2267  	var in1 inner1
  2268  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2269  		"value": float64(1),
  2270  	}, &in1))
  2271  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2272  		"value": float64(0),
  2273  	}, &in1))
  2274  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2275  		"value": float64(5),
  2276  	}, &in1))
  2277  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2278  		"value": json.Number("6"),
  2279  	}, &in1))
  2280  
  2281  	type inner2 struct {
  2282  		Value float64 `key:"value,range=[1:5)"`
  2283  	}
  2284  
  2285  	var in2 inner2
  2286  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2287  		"value": float64(0),
  2288  	}, &in2))
  2289  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2290  		"value": float64(5),
  2291  	}, &in2))
  2292  
  2293  	type inner3 struct {
  2294  		Value float64 `key:"value,range=(1:5]"`
  2295  	}
  2296  
  2297  	var in3 inner3
  2298  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2299  		"value": float64(1),
  2300  	}, &in3))
  2301  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2302  		"value": float64(6),
  2303  	}, &in3))
  2304  
  2305  	type inner4 struct {
  2306  		Value float64 `key:"value,range=[1:5]"`
  2307  	}
  2308  
  2309  	var in4 inner4
  2310  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2311  		"value": float64(0),
  2312  	}, &in4))
  2313  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2314  		"value": float64(6),
  2315  	}, &in4))
  2316  }
  2317  
  2318  func TestUnmarshalRangeError(t *testing.T) {
  2319  	type inner1 struct {
  2320  		Value int `key:",range="`
  2321  	}
  2322  	var in1 inner1
  2323  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2324  		"Value": 1,
  2325  	}, &in1))
  2326  
  2327  	type inner2 struct {
  2328  		Value int `key:",range=["`
  2329  	}
  2330  	var in2 inner2
  2331  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2332  		"Value": 1,
  2333  	}, &in2))
  2334  
  2335  	type inner3 struct {
  2336  		Value int `key:",range=[:"`
  2337  	}
  2338  	var in3 inner3
  2339  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2340  		"Value": 1,
  2341  	}, &in3))
  2342  
  2343  	type inner4 struct {
  2344  		Value int `key:",range=[:]"`
  2345  	}
  2346  	var in4 inner4
  2347  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2348  		"Value": 1,
  2349  	}, &in4))
  2350  
  2351  	type inner5 struct {
  2352  		Value int `key:",range={:]"`
  2353  	}
  2354  	var in5 inner5
  2355  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2356  		"Value": 1,
  2357  	}, &in5))
  2358  
  2359  	type inner6 struct {
  2360  		Value int `key:",range=[:}"`
  2361  	}
  2362  	var in6 inner6
  2363  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2364  		"Value": 1,
  2365  	}, &in6))
  2366  
  2367  	type inner7 struct {
  2368  		Value int `key:",range=[]"`
  2369  	}
  2370  	var in7 inner7
  2371  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2372  		"Value": 1,
  2373  	}, &in7))
  2374  
  2375  	type inner8 struct {
  2376  		Value int `key:",range=[a:]"`
  2377  	}
  2378  	var in8 inner8
  2379  	assert.NotNil(t, UnmarshalKey(map[string]interface{}{
  2380  		"Value": 1,
  2381  	}, &in8))
  2382  
  2383  	type inner9 struct {
  2384  		Value int `key:",range=[:a]"`
  2385  	}
  2386  	var in9 inner9
  2387  	assert.NotNil(t, UnmarshalKey(map[string]interface{}{
  2388  		"Value": 1,
  2389  	}, &in9))
  2390  
  2391  	type inner10 struct {
  2392  		Value int `key:",range"`
  2393  	}
  2394  	var in10 inner10
  2395  	assert.NotNil(t, UnmarshalKey(map[string]interface{}{
  2396  		"Value": 1,
  2397  	}, &in10))
  2398  
  2399  	type inner11 struct {
  2400  		Value int `key:",range=[1,2]"`
  2401  	}
  2402  	var in11 inner11
  2403  	assert.Equal(t, errNumberRange, UnmarshalKey(map[string]interface{}{
  2404  		"Value": "a",
  2405  	}, &in11))
  2406  }
  2407  
  2408  func TestUnmarshalNestedMap(t *testing.T) {
  2409  	var c struct {
  2410  		Anything map[string]map[string]string `json:"anything"`
  2411  	}
  2412  	m := map[string]interface{}{
  2413  		"anything": map[string]map[string]interface{}{
  2414  			"inner": {
  2415  				"id":   "1",
  2416  				"name": "any",
  2417  			},
  2418  		},
  2419  	}
  2420  
  2421  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &c))
  2422  	assert.Equal(t, "1", c.Anything["inner"]["id"])
  2423  }
  2424  
  2425  func TestUnmarshalNestedMapMismatch(t *testing.T) {
  2426  	var c struct {
  2427  		Anything map[string]map[string]map[string]string `json:"anything"`
  2428  	}
  2429  	m := map[string]interface{}{
  2430  		"anything": map[string]map[string]interface{}{
  2431  			"inner": {
  2432  				"name": "any",
  2433  			},
  2434  		},
  2435  	}
  2436  
  2437  	assert.NotNil(t, NewUnmarshaler("json").Unmarshal(m, &c))
  2438  }
  2439  
  2440  func TestUnmarshalNestedMapSimple(t *testing.T) {
  2441  	var c struct {
  2442  		Anything map[string]string `json:"anything"`
  2443  	}
  2444  	m := map[string]interface{}{
  2445  		"anything": map[string]interface{}{
  2446  			"id":   "1",
  2447  			"name": "any",
  2448  		},
  2449  	}
  2450  
  2451  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &c))
  2452  	assert.Equal(t, "1", c.Anything["id"])
  2453  }
  2454  
  2455  func TestUnmarshalNestedMapSimpleTypeMatch(t *testing.T) {
  2456  	var c struct {
  2457  		Anything map[string]string `json:"anything"`
  2458  	}
  2459  	m := map[string]interface{}{
  2460  		"anything": map[string]string{
  2461  			"id":   "1",
  2462  			"name": "any",
  2463  		},
  2464  	}
  2465  
  2466  	assert.Nil(t, NewUnmarshaler("json").Unmarshal(m, &c))
  2467  	assert.Equal(t, "1", c.Anything["id"])
  2468  }
  2469  
  2470  func TestUnmarshalValuer(t *testing.T) {
  2471  	unmarshaler := NewUnmarshaler(jsonTagKey)
  2472  	var foo string
  2473  	err := unmarshaler.UnmarshalValuer(nil, foo)
  2474  	assert.NotNil(t, err)
  2475  }
  2476  
  2477  func BenchmarkUnmarshalString(b *testing.B) {
  2478  	type inner struct {
  2479  		Value string `key:"value"`
  2480  	}
  2481  	m := map[string]interface{}{
  2482  		"value": "first",
  2483  	}
  2484  
  2485  	for i := 0; i < b.N; i++ {
  2486  		var in inner
  2487  		if err := UnmarshalKey(m, &in); err != nil {
  2488  			b.Fatal(err)
  2489  		}
  2490  	}
  2491  }
  2492  
  2493  func BenchmarkUnmarshalStruct(b *testing.B) {
  2494  	b.ReportAllocs()
  2495  
  2496  	m := map[string]interface{}{
  2497  		"Ids": []map[string]interface{}{
  2498  			{
  2499  				"First":  1,
  2500  				"Second": 2,
  2501  			},
  2502  		},
  2503  	}
  2504  
  2505  	for i := 0; i < b.N; i++ {
  2506  		var v struct {
  2507  			Ids []struct {
  2508  				First  int
  2509  				Second int
  2510  			}
  2511  		}
  2512  		if err := UnmarshalKey(m, &v); err != nil {
  2513  			b.Fatal(err)
  2514  		}
  2515  	}
  2516  }
  2517  
  2518  func BenchmarkMapToStruct(b *testing.B) {
  2519  	data := map[string]interface{}{
  2520  		"valid": "1",
  2521  		"age":   "5",
  2522  		"name":  "liao",
  2523  	}
  2524  	type anonymous struct {
  2525  		Valid bool
  2526  		Age   int
  2527  		Name  string
  2528  	}
  2529  
  2530  	for i := 0; i < b.N; i++ {
  2531  		var an anonymous
  2532  		if valid, ok := data["valid"]; ok {
  2533  			an.Valid = valid == "1"
  2534  		}
  2535  		if age, ok := data["age"]; ok {
  2536  			ages, _ := age.(string)
  2537  			an.Age, _ = strconv.Atoi(ages)
  2538  		}
  2539  		if name, ok := data["name"]; ok {
  2540  			names, _ := name.(string)
  2541  			an.Name = names
  2542  		}
  2543  	}
  2544  }
  2545  
  2546  func BenchmarkUnmarshal(b *testing.B) {
  2547  	data := map[string]interface{}{
  2548  		"valid": "1",
  2549  		"age":   "5",
  2550  		"name":  "liao",
  2551  	}
  2552  	type anonymous struct {
  2553  		Valid bool   `key:"valid,string"`
  2554  		Age   int    `key:"age,string"`
  2555  		Name  string `key:"name"`
  2556  	}
  2557  
  2558  	for i := 0; i < b.N; i++ {
  2559  		var an anonymous
  2560  		UnmarshalKey(data, &an)
  2561  	}
  2562  }
  2563  
  2564  func TestUnmarshalJsonReaderMultiArray(t *testing.T) {
  2565  	payload := `{"a": "133", "b": [["add", "cccd"], ["eeee"]]}`
  2566  	var res struct {
  2567  		A string     `json:"a"`
  2568  		B [][]string `json:"b"`
  2569  	}
  2570  	reader := strings.NewReader(payload)
  2571  	err := UnmarshalJsonReader(reader, &res)
  2572  	assert.Nil(t, err)
  2573  	assert.Equal(t, 2, len(res.B))
  2574  }
  2575  
  2576  func TestUnmarshalJsonReaderPtrMultiArray(t *testing.T) {
  2577  	payload := `{"a": "133", "b": [["add", "cccd"], ["eeee"]]}`
  2578  	var res struct {
  2579  		A string      `json:"a"`
  2580  		B [][]*string `json:"b"`
  2581  	}
  2582  	reader := strings.NewReader(payload)
  2583  	err := UnmarshalJsonReader(reader, &res)
  2584  	assert.Nil(t, err)
  2585  	assert.Equal(t, 2, len(res.B))
  2586  	assert.Equal(t, 2, len(res.B[0]))
  2587  }
  2588  
  2589  func TestUnmarshalJsonReaderPtrArray(t *testing.T) {
  2590  	payload := `{"a": "133", "b": ["add", "cccd", "eeee"]}`
  2591  	var res struct {
  2592  		A string    `json:"a"`
  2593  		B []*string `json:"b"`
  2594  	}
  2595  	reader := strings.NewReader(payload)
  2596  	err := UnmarshalJsonReader(reader, &res)
  2597  	assert.Nil(t, err)
  2598  	assert.Equal(t, 3, len(res.B))
  2599  }
  2600  
  2601  func TestUnmarshalJsonWithoutKey(t *testing.T) {
  2602  	payload := `{"A": "1", "B": "2"}`
  2603  	var res struct {
  2604  		A string `json:""`
  2605  		B string `json:","`
  2606  	}
  2607  	reader := strings.NewReader(payload)
  2608  	err := UnmarshalJsonReader(reader, &res)
  2609  	assert.Nil(t, err)
  2610  	assert.Equal(t, "1", res.A)
  2611  	assert.Equal(t, "2", res.B)
  2612  }
  2613  
  2614  func BenchmarkDefaultValue(b *testing.B) {
  2615  	for i := 0; i < b.N; i++ {
  2616  		var a struct {
  2617  			Ints []int    `json:"ints,default=[1,2,3]"`
  2618  			Strs []string `json:"strs,default=[foo,bar,baz]"`
  2619  		}
  2620  		_ = UnmarshalJsonMap(nil, &a)
  2621  		if len(a.Strs) != 3 || len(a.Ints) != 3 {
  2622  			b.Fatal("failed")
  2623  		}
  2624  	}
  2625  }