utils_test.go 7.3 KB

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