github.com/lingyao2333/mo-zero@v1.4.1/core/mapping/utils_test.go (about)

     1  package mapping
     2  
     3  import (
     4  	"reflect"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/assert"
     8  )
     9  
    10  const testTagName = "key"
    11  
    12  type Foo struct {
    13  	Str                 string
    14  	StrWithTag          string `key:"stringwithtag"`
    15  	StrWithTagAndOption string `key:"stringwithtag,string"`
    16  }
    17  
    18  func TestDerefInt(t *testing.T) {
    19  	i := 1
    20  	s := "hello"
    21  	number := struct {
    22  		f float64
    23  	}{
    24  		f: 6.4,
    25  	}
    26  	cases := []struct {
    27  		t      reflect.Type
    28  		expect reflect.Kind
    29  	}{
    30  		{
    31  			t:      reflect.TypeOf(i),
    32  			expect: reflect.Int,
    33  		},
    34  		{
    35  			t:      reflect.TypeOf(&i),
    36  			expect: reflect.Int,
    37  		},
    38  		{
    39  			t:      reflect.TypeOf(s),
    40  			expect: reflect.String,
    41  		},
    42  		{
    43  			t:      reflect.TypeOf(&s),
    44  			expect: reflect.String,
    45  		},
    46  		{
    47  			t:      reflect.TypeOf(number.f),
    48  			expect: reflect.Float64,
    49  		},
    50  		{
    51  			t:      reflect.TypeOf(&number.f),
    52  			expect: reflect.Float64,
    53  		},
    54  	}
    55  
    56  	for _, each := range cases {
    57  		t.Run(each.t.String(), func(t *testing.T) {
    58  			assert.Equal(t, each.expect, Deref(each.t).Kind())
    59  		})
    60  	}
    61  }
    62  
    63  func TestDerefValInt(t *testing.T) {
    64  	i := 1
    65  	s := "hello"
    66  	number := struct {
    67  		f float64
    68  	}{
    69  		f: 6.4,
    70  	}
    71  	cases := []struct {
    72  		t      reflect.Value
    73  		expect reflect.Kind
    74  	}{
    75  		{
    76  			t:      reflect.ValueOf(i),
    77  			expect: reflect.Int,
    78  		},
    79  		{
    80  			t:      reflect.ValueOf(&i),
    81  			expect: reflect.Int,
    82  		},
    83  		{
    84  			t:      reflect.ValueOf(s),
    85  			expect: reflect.String,
    86  		},
    87  		{
    88  			t:      reflect.ValueOf(&s),
    89  			expect: reflect.String,
    90  		},
    91  		{
    92  			t:      reflect.ValueOf(number.f),
    93  			expect: reflect.Float64,
    94  		},
    95  		{
    96  			t:      reflect.ValueOf(&number.f),
    97  			expect: reflect.Float64,
    98  		},
    99  	}
   100  
   101  	for _, each := range cases {
   102  		t.Run(each.t.String(), func(t *testing.T) {
   103  			assert.Equal(t, each.expect, ensureValue(each.t).Kind())
   104  		})
   105  	}
   106  }
   107  
   108  func TestParseKeyAndOptionWithoutTag(t *testing.T) {
   109  	var foo Foo
   110  	rte := reflect.TypeOf(&foo).Elem()
   111  	field, _ := rte.FieldByName("Str")
   112  	key, options, err := parseKeyAndOptions(testTagName, field)
   113  	assert.Nil(t, err)
   114  	assert.Equal(t, "Str", key)
   115  	assert.Nil(t, options)
   116  }
   117  
   118  func TestParseKeyAndOptionWithTagWithoutOption(t *testing.T) {
   119  	var foo Foo
   120  	rte := reflect.TypeOf(&foo).Elem()
   121  	field, _ := rte.FieldByName("StrWithTag")
   122  	key, options, err := parseKeyAndOptions(testTagName, field)
   123  	assert.Nil(t, err)
   124  	assert.Equal(t, "stringwithtag", key)
   125  	assert.Nil(t, options)
   126  }
   127  
   128  func TestParseKeyAndOptionWithTagAndOption(t *testing.T) {
   129  	var foo Foo
   130  	rte := reflect.TypeOf(&foo).Elem()
   131  	field, _ := rte.FieldByName("StrWithTagAndOption")
   132  	key, options, err := parseKeyAndOptions(testTagName, field)
   133  	assert.Nil(t, err)
   134  	assert.Equal(t, "stringwithtag", key)
   135  	assert.True(t, options.FromString)
   136  }
   137  
   138  func TestParseSegments(t *testing.T) {
   139  	tests := []struct {
   140  		input  string
   141  		expect []string
   142  	}{
   143  		{
   144  			input:  "",
   145  			expect: []string{},
   146  		},
   147  		{
   148  			input:  ",",
   149  			expect: []string{""},
   150  		},
   151  		{
   152  			input:  "foo,",
   153  			expect: []string{"foo"},
   154  		},
   155  		{
   156  			input: ",foo",
   157  			// the first empty string cannot be ignored, it's the key.
   158  			expect: []string{"", "foo"},
   159  		},
   160  		{
   161  			input:  "foo",
   162  			expect: []string{"foo"},
   163  		},
   164  		{
   165  			input:  "foo,bar",
   166  			expect: []string{"foo", "bar"},
   167  		},
   168  		{
   169  			input:  "foo,bar,baz",
   170  			expect: []string{"foo", "bar", "baz"},
   171  		},
   172  		{
   173  			input:  "foo,options=a|b",
   174  			expect: []string{"foo", "options=a|b"},
   175  		},
   176  		{
   177  			input:  "foo,bar,default=[baz,qux]",
   178  			expect: []string{"foo", "bar", "default=[baz,qux]"},
   179  		},
   180  		{
   181  			input:  "foo,bar,options=[baz,qux]",
   182  			expect: []string{"foo", "bar", "options=[baz,qux]"},
   183  		},
   184  		{
   185  			input:  `foo\,bar,options=[baz,qux]`,
   186  			expect: []string{`foo,bar`, "options=[baz,qux]"},
   187  		},
   188  		{
   189  			input:  `foo,bar,options=\[baz,qux]`,
   190  			expect: []string{"foo", "bar", "options=[baz", "qux]"},
   191  		},
   192  		{
   193  			input:  `foo,bar,options=[baz\,qux]`,
   194  			expect: []string{"foo", "bar", `options=[baz\,qux]`},
   195  		},
   196  		{
   197  			input:  `foo\,bar,options=[baz,qux],default=baz`,
   198  			expect: []string{`foo,bar`, "options=[baz,qux]", "default=baz"},
   199  		},
   200  		{
   201  			input:  `foo\,bar,options=[baz,qux, quux],default=[qux, baz]`,
   202  			expect: []string{`foo,bar`, "options=[baz,qux, quux]", "default=[qux, baz]"},
   203  		},
   204  	}
   205  
   206  	for _, test := range tests {
   207  		test := test
   208  		t.Run(test.input, func(t *testing.T) {
   209  			assert.ElementsMatch(t, test.expect, parseSegments(test.input))
   210  		})
   211  	}
   212  }
   213  
   214  func TestValidatePtrWithNonPtr(t *testing.T) {
   215  	var foo string
   216  	rve := reflect.ValueOf(foo)
   217  	assert.NotNil(t, ValidatePtr(&rve))
   218  }
   219  
   220  func TestValidatePtrWithPtr(t *testing.T) {
   221  	var foo string
   222  	rve := reflect.ValueOf(&foo)
   223  	assert.Nil(t, ValidatePtr(&rve))
   224  }
   225  
   226  func TestValidatePtrWithNilPtr(t *testing.T) {
   227  	var foo *string
   228  	rve := reflect.ValueOf(foo)
   229  	assert.NotNil(t, ValidatePtr(&rve))
   230  }
   231  
   232  func TestValidatePtrWithZeroValue(t *testing.T) {
   233  	var s string
   234  	e := reflect.Zero(reflect.TypeOf(s))
   235  	assert.NotNil(t, ValidatePtr(&e))
   236  }
   237  
   238  func TestSetValueNotSettable(t *testing.T) {
   239  	var i int
   240  	assert.NotNil(t, setValue(reflect.Int, reflect.ValueOf(i), "1"))
   241  }
   242  
   243  func TestParseKeyAndOptionsErrors(t *testing.T) {
   244  	type Bar struct {
   245  		OptionsValue string `key:",options=a=b"`
   246  		DefaultValue string `key:",default=a=b"`
   247  	}
   248  
   249  	var bar Bar
   250  	_, _, err := parseKeyAndOptions("key", reflect.TypeOf(&bar).Elem().Field(0))
   251  	assert.NotNil(t, err)
   252  	_, _, err = parseKeyAndOptions("key", reflect.TypeOf(&bar).Elem().Field(1))
   253  	assert.NotNil(t, err)
   254  }
   255  
   256  func TestSetValueFormatErrors(t *testing.T) {
   257  	type Bar struct {
   258  		IntValue   int
   259  		UintValue  uint
   260  		FloatValue float32
   261  		MapValue   map[string]interface{}
   262  	}
   263  
   264  	var bar Bar
   265  	tests := []struct {
   266  		kind   reflect.Kind
   267  		target reflect.Value
   268  		value  string
   269  	}{
   270  		{
   271  			kind:   reflect.Int,
   272  			target: reflect.ValueOf(&bar.IntValue).Elem(),
   273  			value:  "a",
   274  		},
   275  		{
   276  			kind:   reflect.Uint,
   277  			target: reflect.ValueOf(&bar.UintValue).Elem(),
   278  			value:  "a",
   279  		},
   280  		{
   281  			kind:   reflect.Float32,
   282  			target: reflect.ValueOf(&bar.FloatValue).Elem(),
   283  			value:  "a",
   284  		},
   285  		{
   286  			kind:   reflect.Map,
   287  			target: reflect.ValueOf(&bar.MapValue).Elem(),
   288  		},
   289  	}
   290  
   291  	for _, test := range tests {
   292  		t.Run(test.kind.String(), func(t *testing.T) {
   293  			err := setValue(test.kind, test.target, test.value)
   294  			assert.NotEqual(t, errValueNotSettable, err)
   295  			assert.NotNil(t, err)
   296  		})
   297  	}
   298  }
   299  
   300  func TestRepr(t *testing.T) {
   301  	var (
   302  		f32 float32 = 1.1
   303  		f64         = 2.2
   304  		i8  int8    = 1
   305  		i16 int16   = 2
   306  		i32 int32   = 3
   307  		i64 int64   = 4
   308  		u8  uint8   = 5
   309  		u16 uint16  = 6
   310  		u32 uint32  = 7
   311  		u64 uint64  = 8
   312  	)
   313  	tests := []struct {
   314  		v      interface{}
   315  		expect string
   316  	}{
   317  		{
   318  			nil,
   319  			"",
   320  		},
   321  		{
   322  			mockStringable{},
   323  			"mocked",
   324  		},
   325  		{
   326  			new(mockStringable),
   327  			"mocked",
   328  		},
   329  		{
   330  			newMockPtr(),
   331  			"mockptr",
   332  		},
   333  		{
   334  			&mockOpacity{
   335  				val: 1,
   336  			},
   337  			"{1}",
   338  		},
   339  		{
   340  			true,
   341  			"true",
   342  		},
   343  		{
   344  			false,
   345  			"false",
   346  		},
   347  		{
   348  			f32,
   349  			"1.1",
   350  		},
   351  		{
   352  			f64,
   353  			"2.2",
   354  		},
   355  		{
   356  			i8,
   357  			"1",
   358  		},
   359  		{
   360  			i16,
   361  			"2",
   362  		},
   363  		{
   364  			i32,
   365  			"3",
   366  		},
   367  		{
   368  			i64,
   369  			"4",
   370  		},
   371  		{
   372  			u8,
   373  			"5",
   374  		},
   375  		{
   376  			u16,
   377  			"6",
   378  		},
   379  		{
   380  			u32,
   381  			"7",
   382  		},
   383  		{
   384  			u64,
   385  			"8",
   386  		},
   387  		{
   388  			[]byte(`abcd`),
   389  			"abcd",
   390  		},
   391  		{
   392  			mockOpacity{val: 1},
   393  			"{1}",
   394  		},
   395  	}
   396  
   397  	for _, test := range tests {
   398  		t.Run(test.expect, func(t *testing.T) {
   399  			assert.Equal(t, test.expect, Repr(test.v))
   400  		})
   401  	}
   402  }
   403  
   404  type mockStringable struct{}
   405  
   406  func (m mockStringable) String() string {
   407  	return "mocked"
   408  }
   409  
   410  type mockPtr struct{}
   411  
   412  func newMockPtr() *mockPtr {
   413  	return new(mockPtr)
   414  }
   415  
   416  func (m *mockPtr) String() string {
   417  	return "mockptr"
   418  }
   419  
   420  type mockOpacity struct {
   421  	val int
   422  }