utils_test.go 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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: ",",
  141. expect: []string{""},
  142. },
  143. {
  144. input: "foo,",
  145. expect: []string{"foo"},
  146. },
  147. {
  148. input: ",foo",
  149. // the first empty string cannot be ignored, it's the key.
  150. expect: []string{"", "foo"},
  151. },
  152. {
  153. input: "foo",
  154. expect: []string{"foo"},
  155. },
  156. {
  157. input: "foo,bar",
  158. expect: []string{"foo", "bar"},
  159. },
  160. {
  161. input: "foo,bar,baz",
  162. expect: []string{"foo", "bar", "baz"},
  163. },
  164. {
  165. input: "foo,options=a|b",
  166. expect: []string{"foo", "options=a|b"},
  167. },
  168. {
  169. input: "foo,bar,default=[baz,qux]",
  170. expect: []string{"foo", "bar", "default=[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]`,
  186. expect: []string{"foo", "bar", `options=[baz\,qux]`},
  187. },
  188. {
  189. input: `foo\,bar,options=[baz,qux],default=baz`,
  190. expect: []string{`foo,bar`, "options=[baz,qux]", "default=baz"},
  191. },
  192. {
  193. input: `foo\,bar,options=[baz,qux, quux],default=[qux, baz]`,
  194. expect: []string{`foo,bar`, "options=[baz,qux, quux]", "default=[qux, baz]"},
  195. },
  196. }
  197. for _, test := range tests {
  198. test := test
  199. t.Run(test.input, func(t *testing.T) {
  200. assert.ElementsMatch(t, test.expect, parseSegments(test.input))
  201. })
  202. }
  203. }
  204. func TestValidatePtrWithNonPtr(t *testing.T) {
  205. var foo string
  206. rve := reflect.ValueOf(foo)
  207. assert.NotNil(t, ValidatePtr(&rve))
  208. }
  209. func TestValidatePtrWithPtr(t *testing.T) {
  210. var foo string
  211. rve := reflect.ValueOf(&foo)
  212. assert.Nil(t, ValidatePtr(&rve))
  213. }
  214. func TestValidatePtrWithNilPtr(t *testing.T) {
  215. var foo *string
  216. rve := reflect.ValueOf(foo)
  217. assert.NotNil(t, ValidatePtr(&rve))
  218. }
  219. func TestValidatePtrWithZeroValue(t *testing.T) {
  220. var s string
  221. e := reflect.Zero(reflect.TypeOf(s))
  222. assert.NotNil(t, ValidatePtr(&e))
  223. }
  224. func TestSetValueNotSettable(t *testing.T) {
  225. var i int
  226. assert.NotNil(t, setValueFromString(reflect.Int, reflect.ValueOf(i), "1"))
  227. }
  228. func TestParseKeyAndOptionsErrors(t *testing.T) {
  229. type Bar struct {
  230. OptionsValue string `key:",options=a=b"`
  231. DefaultValue string `key:",default=a=b"`
  232. }
  233. var bar Bar
  234. _, _, err := parseKeyAndOptions("key", reflect.TypeOf(&bar).Elem().Field(0))
  235. assert.NotNil(t, err)
  236. _, _, err = parseKeyAndOptions("key", reflect.TypeOf(&bar).Elem().Field(1))
  237. assert.NotNil(t, err)
  238. }
  239. func TestSetValueFormatErrors(t *testing.T) {
  240. type Bar struct {
  241. IntValue int
  242. UintValue uint
  243. FloatValue float32
  244. MapValue map[string]any
  245. }
  246. var bar Bar
  247. tests := []struct {
  248. kind reflect.Kind
  249. target reflect.Value
  250. value string
  251. }{
  252. {
  253. kind: reflect.Int,
  254. target: reflect.ValueOf(&bar.IntValue).Elem(),
  255. value: "a",
  256. },
  257. {
  258. kind: reflect.Uint,
  259. target: reflect.ValueOf(&bar.UintValue).Elem(),
  260. value: "a",
  261. },
  262. {
  263. kind: reflect.Float32,
  264. target: reflect.ValueOf(&bar.FloatValue).Elem(),
  265. value: "a",
  266. },
  267. {
  268. kind: reflect.Map,
  269. target: reflect.ValueOf(&bar.MapValue).Elem(),
  270. },
  271. }
  272. for _, test := range tests {
  273. t.Run(test.kind.String(), func(t *testing.T) {
  274. err := setValueFromString(test.kind, test.target, test.value)
  275. assert.NotEqual(t, errValueNotSettable, err)
  276. assert.NotNil(t, err)
  277. })
  278. }
  279. }