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 }