github.com/shuguocloud/go-zero@v1.3.0/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 TestDeferInt(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 TestParseKeyAndOptionWithoutTag(t *testing.T) {
    64  	var foo Foo
    65  	rte := reflect.TypeOf(&foo).Elem()
    66  	field, _ := rte.FieldByName("Str")
    67  	key, options, err := parseKeyAndOptions(testTagName, field)
    68  	assert.Nil(t, err)
    69  	assert.Equal(t, "Str", key)
    70  	assert.Nil(t, options)
    71  }
    72  
    73  func TestParseKeyAndOptionWithTagWithoutOption(t *testing.T) {
    74  	var foo Foo
    75  	rte := reflect.TypeOf(&foo).Elem()
    76  	field, _ := rte.FieldByName("StrWithTag")
    77  	key, options, err := parseKeyAndOptions(testTagName, field)
    78  	assert.Nil(t, err)
    79  	assert.Equal(t, "stringwithtag", key)
    80  	assert.Nil(t, options)
    81  }
    82  
    83  func TestParseKeyAndOptionWithTagAndOption(t *testing.T) {
    84  	var foo Foo
    85  	rte := reflect.TypeOf(&foo).Elem()
    86  	field, _ := rte.FieldByName("StrWithTagAndOption")
    87  	key, options, err := parseKeyAndOptions(testTagName, field)
    88  	assert.Nil(t, err)
    89  	assert.Equal(t, "stringwithtag", key)
    90  	assert.True(t, options.FromString)
    91  }
    92  
    93  func TestParseSegments(t *testing.T) {
    94  	tests := []struct {
    95  		input  string
    96  		expect []string
    97  	}{
    98  		{
    99  			input:  "",
   100  			expect: []string{},
   101  		},
   102  		{
   103  			input:  ",",
   104  			expect: []string{""},
   105  		},
   106  		{
   107  			input:  "foo,",
   108  			expect: []string{"foo"},
   109  		},
   110  		{
   111  			input: ",foo",
   112  			// the first empty string cannot be ignored, it's the key.
   113  			expect: []string{"", "foo"},
   114  		},
   115  		{
   116  			input:  "foo",
   117  			expect: []string{"foo"},
   118  		},
   119  		{
   120  			input:  "foo,bar",
   121  			expect: []string{"foo", "bar"},
   122  		},
   123  		{
   124  			input:  "foo,bar,baz",
   125  			expect: []string{"foo", "bar", "baz"},
   126  		},
   127  		{
   128  			input:  "foo,options=a|b",
   129  			expect: []string{"foo", "options=a|b"},
   130  		},
   131  		{
   132  			input:  "foo,bar,default=[baz,qux]",
   133  			expect: []string{"foo", "bar", "default=[baz,qux]"},
   134  		},
   135  		{
   136  			input:  "foo,bar,options=[baz,qux]",
   137  			expect: []string{"foo", "bar", "options=[baz,qux]"},
   138  		},
   139  		{
   140  			input:  `foo\,bar,options=[baz,qux]`,
   141  			expect: []string{`foo,bar`, "options=[baz,qux]"},
   142  		},
   143  		{
   144  			input:  `foo,bar,options=\[baz,qux]`,
   145  			expect: []string{"foo", "bar", "options=[baz", "qux]"},
   146  		},
   147  		{
   148  			input:  `foo,bar,options=[baz\,qux]`,
   149  			expect: []string{"foo", "bar", `options=[baz\,qux]`},
   150  		},
   151  		{
   152  			input:  `foo\,bar,options=[baz,qux],default=baz`,
   153  			expect: []string{`foo,bar`, "options=[baz,qux]", "default=baz"},
   154  		},
   155  		{
   156  			input:  `foo\,bar,options=[baz,qux, quux],default=[qux, baz]`,
   157  			expect: []string{`foo,bar`, "options=[baz,qux, quux]", "default=[qux, baz]"},
   158  		},
   159  	}
   160  
   161  	for _, test := range tests {
   162  		test := test
   163  		t.Run(test.input, func(t *testing.T) {
   164  			assert.ElementsMatch(t, test.expect, parseSegments(test.input))
   165  		})
   166  	}
   167  }
   168  
   169  func TestValidatePtrWithNonPtr(t *testing.T) {
   170  	var foo string
   171  	rve := reflect.ValueOf(foo)
   172  	assert.NotNil(t, ValidatePtr(&rve))
   173  }
   174  
   175  func TestValidatePtrWithPtr(t *testing.T) {
   176  	var foo string
   177  	rve := reflect.ValueOf(&foo)
   178  	assert.Nil(t, ValidatePtr(&rve))
   179  }
   180  
   181  func TestValidatePtrWithNilPtr(t *testing.T) {
   182  	var foo *string
   183  	rve := reflect.ValueOf(foo)
   184  	assert.NotNil(t, ValidatePtr(&rve))
   185  }
   186  
   187  func TestValidatePtrWithZeroValue(t *testing.T) {
   188  	var s string
   189  	e := reflect.Zero(reflect.TypeOf(s))
   190  	assert.NotNil(t, ValidatePtr(&e))
   191  }
   192  
   193  func TestSetValueNotSettable(t *testing.T) {
   194  	var i int
   195  	assert.NotNil(t, setValue(reflect.Int, reflect.ValueOf(i), "1"))
   196  }
   197  
   198  func TestParseKeyAndOptionsErrors(t *testing.T) {
   199  	type Bar struct {
   200  		OptionsValue string `key:",options=a=b"`
   201  		DefaultValue string `key:",default=a=b"`
   202  	}
   203  
   204  	var bar Bar
   205  	_, _, err := parseKeyAndOptions("key", reflect.TypeOf(&bar).Elem().Field(0))
   206  	assert.NotNil(t, err)
   207  	_, _, err = parseKeyAndOptions("key", reflect.TypeOf(&bar).Elem().Field(1))
   208  	assert.NotNil(t, err)
   209  }
   210  
   211  func TestSetValueFormatErrors(t *testing.T) {
   212  	type Bar struct {
   213  		IntValue   int
   214  		UintValue  uint
   215  		FloatValue float32
   216  		MapValue   map[string]interface{}
   217  	}
   218  
   219  	var bar Bar
   220  	tests := []struct {
   221  		kind   reflect.Kind
   222  		target reflect.Value
   223  		value  string
   224  	}{
   225  		{
   226  			kind:   reflect.Int,
   227  			target: reflect.ValueOf(&bar.IntValue).Elem(),
   228  			value:  "a",
   229  		},
   230  		{
   231  			kind:   reflect.Uint,
   232  			target: reflect.ValueOf(&bar.UintValue).Elem(),
   233  			value:  "a",
   234  		},
   235  		{
   236  			kind:   reflect.Float32,
   237  			target: reflect.ValueOf(&bar.FloatValue).Elem(),
   238  			value:  "a",
   239  		},
   240  		{
   241  			kind:   reflect.Map,
   242  			target: reflect.ValueOf(&bar.MapValue).Elem(),
   243  		},
   244  	}
   245  
   246  	for _, test := range tests {
   247  		t.Run(test.kind.String(), func(t *testing.T) {
   248  			err := setValue(test.kind, test.target, test.value)
   249  			assert.NotEqual(t, errValueNotSettable, err)
   250  			assert.NotNil(t, err)
   251  		})
   252  	}
   253  }
   254  
   255  func TestRepr(t *testing.T) {
   256  	var (
   257  		f32 float32 = 1.1
   258  		f64         = 2.2
   259  		i8  int8    = 1
   260  		i16 int16   = 2
   261  		i32 int32   = 3
   262  		i64 int64   = 4
   263  		u8  uint8   = 5
   264  		u16 uint16  = 6
   265  		u32 uint32  = 7
   266  		u64 uint64  = 8
   267  	)
   268  	tests := []struct {
   269  		v      interface{}
   270  		expect string
   271  	}{
   272  		{
   273  			nil,
   274  			"",
   275  		},
   276  		{
   277  			mockStringable{},
   278  			"mocked",
   279  		},
   280  		{
   281  			new(mockStringable),
   282  			"mocked",
   283  		},
   284  		{
   285  			newMockPtr(),
   286  			"mockptr",
   287  		},
   288  		{
   289  			&mockOpacity{
   290  				val: 1,
   291  			},
   292  			"{1}",
   293  		},
   294  		{
   295  			true,
   296  			"true",
   297  		},
   298  		{
   299  			false,
   300  			"false",
   301  		},
   302  		{
   303  			f32,
   304  			"1.1",
   305  		},
   306  		{
   307  			f64,
   308  			"2.2",
   309  		},
   310  		{
   311  			i8,
   312  			"1",
   313  		},
   314  		{
   315  			i16,
   316  			"2",
   317  		},
   318  		{
   319  			i32,
   320  			"3",
   321  		},
   322  		{
   323  			i64,
   324  			"4",
   325  		},
   326  		{
   327  			u8,
   328  			"5",
   329  		},
   330  		{
   331  			u16,
   332  			"6",
   333  		},
   334  		{
   335  			u32,
   336  			"7",
   337  		},
   338  		{
   339  			u64,
   340  			"8",
   341  		},
   342  		{
   343  			[]byte(`abcd`),
   344  			"abcd",
   345  		},
   346  		{
   347  			mockOpacity{val: 1},
   348  			"{1}",
   349  		},
   350  	}
   351  
   352  	for _, test := range tests {
   353  		t.Run(test.expect, func(t *testing.T) {
   354  			assert.Equal(t, test.expect, Repr(test.v))
   355  		})
   356  	}
   357  }
   358  
   359  type mockStringable struct{}
   360  
   361  func (m mockStringable) String() string {
   362  	return "mocked"
   363  }
   364  
   365  type mockPtr struct{}
   366  
   367  func newMockPtr() *mockPtr {
   368  	return new(mockPtr)
   369  }
   370  
   371  func (m *mockPtr) String() string {
   372  	return "mockptr"
   373  }
   374  
   375  type mockOpacity struct {
   376  	val int
   377  }