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