github.com/hduhelp/go-zero@v1.4.3/core/mapping/unmarshaler_test.go (about)

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