utils_test.go 6.6 KB

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