form_mapping_test.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271
  1. // Copyright 2019 Gin Core Team. All rights reserved.
  2. // Use of this source code is governed by a MIT style
  3. // license that can be found in the LICENSE file.
  4. package binding
  5. import (
  6. "reflect"
  7. "testing"
  8. "time"
  9. "github.com/stretchr/testify/assert"
  10. )
  11. func TestMappingBaseTypes(t *testing.T) {
  12. intPtr := func(i int) *int {
  13. return &i
  14. }
  15. for _, tt := range []struct {
  16. name string
  17. value interface{}
  18. form string
  19. expect interface{}
  20. }{
  21. {"base type", struct{ F int }{}, "9", int(9)},
  22. {"base type", struct{ F int8 }{}, "9", int8(9)},
  23. {"base type", struct{ F int16 }{}, "9", int16(9)},
  24. {"base type", struct{ F int32 }{}, "9", int32(9)},
  25. {"base type", struct{ F int64 }{}, "9", int64(9)},
  26. {"base type", struct{ F uint }{}, "9", uint(9)},
  27. {"base type", struct{ F uint8 }{}, "9", uint8(9)},
  28. {"base type", struct{ F uint16 }{}, "9", uint16(9)},
  29. {"base type", struct{ F uint32 }{}, "9", uint32(9)},
  30. {"base type", struct{ F uint64 }{}, "9", uint64(9)},
  31. {"base type", struct{ F bool }{}, "True", true},
  32. {"base type", struct{ F float32 }{}, "9.1", float32(9.1)},
  33. {"base type", struct{ F float64 }{}, "9.1", float64(9.1)},
  34. {"base type", struct{ F string }{}, "test", string("test")},
  35. {"base type", struct{ F *int }{}, "9", intPtr(9)},
  36. // zero values
  37. {"zero value", struct{ F int }{}, "", int(0)},
  38. {"zero value", struct{ F uint }{}, "", uint(0)},
  39. {"zero value", struct{ F bool }{}, "", false},
  40. {"zero value", struct{ F float32 }{}, "", float32(0)},
  41. } {
  42. tp := reflect.TypeOf(tt.value)
  43. testName := tt.name + ":" + tp.Field(0).Type.String()
  44. val := reflect.New(reflect.TypeOf(tt.value))
  45. val.Elem().Set(reflect.ValueOf(tt.value))
  46. field := val.Elem().Type().Field(0)
  47. _, err := mapping(val, emptyField, formSource{field.Name: {tt.form}}, "form")
  48. assert.NoError(t, err, testName)
  49. actual := val.Elem().Field(0).Interface()
  50. assert.Equal(t, tt.expect, actual, testName)
  51. }
  52. }
  53. func TestMappingDefault(t *testing.T) {
  54. var s struct {
  55. Int int `form:",default=9"`
  56. Slice []int `form:",default=9"`
  57. Array [1]int `form:",default=9"`
  58. }
  59. err := mappingByPtr(&s, formSource{}, "form")
  60. assert.NoError(t, err)
  61. assert.Equal(t, 9, s.Int)
  62. assert.Equal(t, []int{9}, s.Slice)
  63. assert.Equal(t, [1]int{9}, s.Array)
  64. }
  65. func TestMappingSkipField(t *testing.T) {
  66. var s struct {
  67. A int
  68. }
  69. err := mappingByPtr(&s, formSource{}, "form")
  70. assert.NoError(t, err)
  71. assert.Equal(t, 0, s.A)
  72. }
  73. func TestMappingIgnoreField(t *testing.T) {
  74. var s struct {
  75. A int `form:"A"`
  76. B int `form:"-"`
  77. }
  78. err := mappingByPtr(&s, formSource{"A": {"9"}, "B": {"9"}}, "form")
  79. assert.NoError(t, err)
  80. assert.Equal(t, 9, s.A)
  81. assert.Equal(t, 0, s.B)
  82. }
  83. func TestMappingUnexportedField(t *testing.T) {
  84. var s struct {
  85. A int `form:"a"`
  86. b int `form:"b"`
  87. }
  88. err := mappingByPtr(&s, formSource{"a": {"9"}, "b": {"9"}}, "form")
  89. assert.NoError(t, err)
  90. assert.Equal(t, 9, s.A)
  91. assert.Equal(t, 0, s.b)
  92. }
  93. func TestMappingPrivateField(t *testing.T) {
  94. var s struct {
  95. f int `form:"field"`
  96. }
  97. err := mappingByPtr(&s, formSource{"field": {"6"}}, "form")
  98. assert.NoError(t, err)
  99. assert.Equal(t, int(0), s.f)
  100. }
  101. func TestMappingUnknownFieldType(t *testing.T) {
  102. var s struct {
  103. U uintptr
  104. }
  105. err := mappingByPtr(&s, formSource{"U": {"unknown"}}, "form")
  106. assert.Error(t, err)
  107. assert.Equal(t, errUnknownType, err)
  108. }
  109. func TestMappingURI(t *testing.T) {
  110. var s struct {
  111. F int `uri:"field"`
  112. }
  113. err := mapUri(&s, map[string][]string{"field": {"6"}})
  114. assert.NoError(t, err)
  115. assert.Equal(t, int(6), s.F)
  116. }
  117. func TestMappingForm(t *testing.T) {
  118. var s struct {
  119. F int `form:"field"`
  120. }
  121. err := mapForm(&s, map[string][]string{"field": {"6"}})
  122. assert.NoError(t, err)
  123. assert.Equal(t, int(6), s.F)
  124. }
  125. func TestMappingTime(t *testing.T) {
  126. var s struct {
  127. Time time.Time
  128. LocalTime time.Time `time_format:"2006-01-02"`
  129. ZeroValue time.Time
  130. CSTTime time.Time `time_format:"2006-01-02" time_location:"Asia/Shanghai"`
  131. UTCTime time.Time `time_format:"2006-01-02" time_utc:"1"`
  132. }
  133. var err error
  134. time.Local, err = time.LoadLocation("Europe/Berlin")
  135. assert.NoError(t, err)
  136. err = mapForm(&s, map[string][]string{
  137. "Time": {"2019-01-20T16:02:58Z"},
  138. "LocalTime": {"2019-01-20"},
  139. "ZeroValue": {},
  140. "CSTTime": {"2019-01-20"},
  141. "UTCTime": {"2019-01-20"},
  142. })
  143. assert.NoError(t, err)
  144. assert.Equal(t, "2019-01-20 16:02:58 +0000 UTC", s.Time.String())
  145. assert.Equal(t, "2019-01-20 00:00:00 +0100 CET", s.LocalTime.String())
  146. assert.Equal(t, "2019-01-19 23:00:00 +0000 UTC", s.LocalTime.UTC().String())
  147. assert.Equal(t, "0001-01-01 00:00:00 +0000 UTC", s.ZeroValue.String())
  148. assert.Equal(t, "2019-01-20 00:00:00 +0800 CST", s.CSTTime.String())
  149. assert.Equal(t, "2019-01-19 16:00:00 +0000 UTC", s.CSTTime.UTC().String())
  150. assert.Equal(t, "2019-01-20 00:00:00 +0000 UTC", s.UTCTime.String())
  151. // wrong location
  152. var wrongLoc struct {
  153. Time time.Time `time_location:"wrong"`
  154. }
  155. err = mapForm(&wrongLoc, map[string][]string{"Time": {"2019-01-20T16:02:58Z"}})
  156. assert.Error(t, err)
  157. // wrong time value
  158. var wrongTime struct {
  159. Time time.Time
  160. }
  161. err = mapForm(&wrongTime, map[string][]string{"Time": {"wrong"}})
  162. assert.Error(t, err)
  163. }
  164. func TestMapiingTimeDuration(t *testing.T) {
  165. var s struct {
  166. D time.Duration
  167. }
  168. // ok
  169. err := mappingByPtr(&s, formSource{"D": {"5s"}}, "form")
  170. assert.NoError(t, err)
  171. assert.Equal(t, 5*time.Second, s.D)
  172. // error
  173. err = mappingByPtr(&s, formSource{"D": {"wrong"}}, "form")
  174. assert.Error(t, err)
  175. }
  176. func TestMappingSlice(t *testing.T) {
  177. var s struct {
  178. Slice []int `form:"slice,default=9"`
  179. }
  180. // default value
  181. err := mappingByPtr(&s, formSource{}, "form")
  182. assert.NoError(t, err)
  183. assert.Equal(t, []int{9}, s.Slice)
  184. // ok
  185. err = mappingByPtr(&s, formSource{"slice": {"3", "4"}}, "form")
  186. assert.NoError(t, err)
  187. assert.Equal(t, []int{3, 4}, s.Slice)
  188. // error
  189. err = mappingByPtr(&s, formSource{"slice": {"wrong"}}, "form")
  190. assert.Error(t, err)
  191. }
  192. func TestMappingArray(t *testing.T) {
  193. var s struct {
  194. Array [2]int `form:"array,default=9"`
  195. }
  196. // wrong default
  197. err := mappingByPtr(&s, formSource{}, "form")
  198. assert.Error(t, err)
  199. // ok
  200. err = mappingByPtr(&s, formSource{"array": {"3", "4"}}, "form")
  201. assert.NoError(t, err)
  202. assert.Equal(t, [2]int{3, 4}, s.Array)
  203. // error - not enough vals
  204. err = mappingByPtr(&s, formSource{"array": {"3"}}, "form")
  205. assert.Error(t, err)
  206. // error - wrong value
  207. err = mappingByPtr(&s, formSource{"array": {"wrong"}}, "form")
  208. assert.Error(t, err)
  209. }
  210. func TestMappingStructField(t *testing.T) {
  211. var s struct {
  212. J struct {
  213. I int
  214. }
  215. }
  216. err := mappingByPtr(&s, formSource{"J": {`{"I": 9}`}}, "form")
  217. assert.NoError(t, err)
  218. assert.Equal(t, 9, s.J.I)
  219. }
  220. func TestMappingMapField(t *testing.T) {
  221. var s struct {
  222. M map[string]int
  223. }
  224. err := mappingByPtr(&s, formSource{"M": {`{"one": 1}`}}, "form")
  225. assert.NoError(t, err)
  226. assert.Equal(t, map[string]int{"one": 1}, s.M)
  227. }