1
0

utils_test.go 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  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.Error(t, setValueFromString(reflect.Int, reflect.ValueOf(i), "1"))
  227. assert.Error(t, validateAndSetValue(reflect.Int, reflect.ValueOf(i), "1", nil))
  228. }
  229. func TestParseKeyAndOptionsErrors(t *testing.T) {
  230. type Bar struct {
  231. OptionsValue string `key:",options=a=b"`
  232. DefaultValue string `key:",default=a=b"`
  233. }
  234. var bar Bar
  235. _, _, err := parseKeyAndOptions("key", reflect.TypeOf(&bar).Elem().Field(0))
  236. assert.NotNil(t, err)
  237. _, _, err = parseKeyAndOptions("key", reflect.TypeOf(&bar).Elem().Field(1))
  238. assert.NotNil(t, err)
  239. }
  240. func TestSetValueFormatErrors(t *testing.T) {
  241. type Bar struct {
  242. IntValue int
  243. UintValue uint
  244. FloatValue float32
  245. MapValue map[string]any
  246. }
  247. var bar Bar
  248. tests := []struct {
  249. kind reflect.Kind
  250. target reflect.Value
  251. value string
  252. }{
  253. {
  254. kind: reflect.Int,
  255. target: reflect.ValueOf(&bar.IntValue).Elem(),
  256. value: "a",
  257. },
  258. {
  259. kind: reflect.Uint,
  260. target: reflect.ValueOf(&bar.UintValue).Elem(),
  261. value: "a",
  262. },
  263. {
  264. kind: reflect.Float32,
  265. target: reflect.ValueOf(&bar.FloatValue).Elem(),
  266. value: "a",
  267. },
  268. {
  269. kind: reflect.Map,
  270. target: reflect.ValueOf(&bar.MapValue).Elem(),
  271. },
  272. }
  273. for _, test := range tests {
  274. t.Run(test.kind.String(), func(t *testing.T) {
  275. err := setValueFromString(test.kind, test.target, test.value)
  276. assert.NotEqual(t, errValueNotSettable, err)
  277. assert.NotNil(t, err)
  278. })
  279. }
  280. }
  281. func TestValidateValueRange(t *testing.T) {
  282. t.Run("float", func(t *testing.T) {
  283. assert.NoError(t, validateValueRange(1.2, nil))
  284. })
  285. t.Run("float number range", func(t *testing.T) {
  286. assert.NoError(t, validateNumberRange(1.2, nil))
  287. })
  288. t.Run("bad float", func(t *testing.T) {
  289. assert.Error(t, validateValueRange("a", &fieldOptionsWithContext{
  290. Range: &numberRange{},
  291. }))
  292. })
  293. t.Run("bad float validate", func(t *testing.T) {
  294. var v struct {
  295. Foo float32
  296. }
  297. assert.Error(t, validateAndSetValue(reflect.Int, reflect.ValueOf(&v).Elem().Field(0),
  298. "1", &fieldOptionsWithContext{
  299. Range: &numberRange{
  300. left: 2,
  301. right: 3,
  302. },
  303. }))
  304. })
  305. }
  306. func TestSetMatchedPrimitiveValue(t *testing.T) {
  307. assert.Error(t, setMatchedPrimitiveValue(reflect.Func, reflect.ValueOf(2), "1"))
  308. }