utils_test.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  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, setValueFromString(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]any
  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 := setValueFromString(test.kind, test.target, test.value)
  271. assert.NotEqual(t, errValueNotSettable, err)
  272. assert.NotNil(t, err)
  273. })
  274. }
  275. }