1
2
3
4
5 package binding
6
7 import (
8 "reflect"
9 "testing"
10 "time"
11
12 "github.com/stretchr/testify/assert"
13 )
14
15 func TestMappingBaseTypes(t *testing.T) {
16 intPtr := func(i int) *int {
17 return &i
18 }
19 for _, tt := range []struct {
20 name string
21 value any
22 form string
23 expect any
24 }{
25 {"base type", struct{ F int }{}, "9", int(9)},
26 {"base type", struct{ F int8 }{}, "9", int8(9)},
27 {"base type", struct{ F int16 }{}, "9", int16(9)},
28 {"base type", struct{ F int32 }{}, "9", int32(9)},
29 {"base type", struct{ F int64 }{}, "9", int64(9)},
30 {"base type", struct{ F uint }{}, "9", uint(9)},
31 {"base type", struct{ F uint8 }{}, "9", uint8(9)},
32 {"base type", struct{ F uint16 }{}, "9", uint16(9)},
33 {"base type", struct{ F uint32 }{}, "9", uint32(9)},
34 {"base type", struct{ F uint64 }{}, "9", uint64(9)},
35 {"base type", struct{ F bool }{}, "True", true},
36 {"base type", struct{ F float32 }{}, "9.1", float32(9.1)},
37 {"base type", struct{ F float64 }{}, "9.1", float64(9.1)},
38 {"base type", struct{ F string }{}, "test", string("test")},
39 {"base type", struct{ F *int }{}, "9", intPtr(9)},
40
41
42 {"zero value", struct{ F int }{}, "", int(0)},
43 {"zero value", struct{ F uint }{}, "", uint(0)},
44 {"zero value", struct{ F bool }{}, "", false},
45 {"zero value", struct{ F float32 }{}, "", float32(0)},
46 } {
47 tp := reflect.TypeOf(tt.value)
48 testName := tt.name + ":" + tp.Field(0).Type.String()
49
50 val := reflect.New(reflect.TypeOf(tt.value))
51 val.Elem().Set(reflect.ValueOf(tt.value))
52
53 field := val.Elem().Type().Field(0)
54
55 _, err := mapping(val, emptyField, formSource{field.Name: {tt.form}}, "form")
56 assert.NoError(t, err, testName)
57
58 actual := val.Elem().Field(0).Interface()
59 assert.Equal(t, tt.expect, actual, testName)
60 }
61 }
62
63 func TestMappingDefault(t *testing.T) {
64 var s struct {
65 Int int `form:",default=9"`
66 Slice []int `form:",default=9"`
67 Array [1]int `form:",default=9"`
68 }
69 err := mappingByPtr(&s, formSource{}, "form")
70 assert.NoError(t, err)
71
72 assert.Equal(t, 9, s.Int)
73 assert.Equal(t, []int{9}, s.Slice)
74 assert.Equal(t, [1]int{9}, s.Array)
75 }
76
77 func TestMappingSkipField(t *testing.T) {
78 var s struct {
79 A int
80 }
81 err := mappingByPtr(&s, formSource{}, "form")
82 assert.NoError(t, err)
83
84 assert.Equal(t, 0, s.A)
85 }
86
87 func TestMappingIgnoreField(t *testing.T) {
88 var s struct {
89 A int `form:"A"`
90 B int `form:"-"`
91 }
92 err := mappingByPtr(&s, formSource{"A": {"9"}, "B": {"9"}}, "form")
93 assert.NoError(t, err)
94
95 assert.Equal(t, 9, s.A)
96 assert.Equal(t, 0, s.B)
97 }
98
99 func TestMappingUnexportedField(t *testing.T) {
100 var s struct {
101 A int `form:"a"`
102 b int `form:"b"`
103 }
104 err := mappingByPtr(&s, formSource{"a": {"9"}, "b": {"9"}}, "form")
105 assert.NoError(t, err)
106
107 assert.Equal(t, 9, s.A)
108 assert.Equal(t, 0, s.b)
109 }
110
111 func TestMappingPrivateField(t *testing.T) {
112 var s struct {
113 f int `form:"field"`
114 }
115 err := mappingByPtr(&s, formSource{"field": {"6"}}, "form")
116 assert.NoError(t, err)
117 assert.Equal(t, 0, s.f)
118 }
119
120 func TestMappingUnknownFieldType(t *testing.T) {
121 var s struct {
122 U uintptr
123 }
124
125 err := mappingByPtr(&s, formSource{"U": {"unknown"}}, "form")
126 assert.Error(t, err)
127 assert.Equal(t, errUnknownType, err)
128 }
129
130 func TestMappingURI(t *testing.T) {
131 var s struct {
132 F int `uri:"field"`
133 }
134 err := mapURI(&s, map[string][]string{"field": {"6"}})
135 assert.NoError(t, err)
136 assert.Equal(t, 6, s.F)
137 }
138
139 func TestMappingForm(t *testing.T) {
140 var s struct {
141 F int `form:"field"`
142 }
143 err := mapForm(&s, map[string][]string{"field": {"6"}})
144 assert.NoError(t, err)
145 assert.Equal(t, 6, s.F)
146 }
147
148 func TestMapFormWithTag(t *testing.T) {
149 var s struct {
150 F int `externalTag:"field"`
151 }
152 err := MapFormWithTag(&s, map[string][]string{"field": {"6"}}, "externalTag")
153 assert.NoError(t, err)
154 assert.Equal(t, 6, s.F)
155 }
156
157 func TestMappingTime(t *testing.T) {
158 var s struct {
159 Time time.Time
160 LocalTime time.Time `time_format:"2006-01-02"`
161 ZeroValue time.Time
162 CSTTime time.Time `time_format:"2006-01-02" time_location:"Asia/Shanghai"`
163 UTCTime time.Time `time_format:"2006-01-02" time_utc:"1"`
164 }
165
166 var err error
167 time.Local, err = time.LoadLocation("Europe/Berlin")
168 assert.NoError(t, err)
169
170 err = mapForm(&s, map[string][]string{
171 "Time": {"2019-01-20T16:02:58Z"},
172 "LocalTime": {"2019-01-20"},
173 "ZeroValue": {},
174 "CSTTime": {"2019-01-20"},
175 "UTCTime": {"2019-01-20"},
176 })
177 assert.NoError(t, err)
178
179 assert.Equal(t, "2019-01-20 16:02:58 +0000 UTC", s.Time.String())
180 assert.Equal(t, "2019-01-20 00:00:00 +0100 CET", s.LocalTime.String())
181 assert.Equal(t, "2019-01-19 23:00:00 +0000 UTC", s.LocalTime.UTC().String())
182 assert.Equal(t, "0001-01-01 00:00:00 +0000 UTC", s.ZeroValue.String())
183 assert.Equal(t, "2019-01-20 00:00:00 +0800 CST", s.CSTTime.String())
184 assert.Equal(t, "2019-01-19 16:00:00 +0000 UTC", s.CSTTime.UTC().String())
185 assert.Equal(t, "2019-01-20 00:00:00 +0000 UTC", s.UTCTime.String())
186
187
188 var wrongLoc struct {
189 Time time.Time `time_location:"wrong"`
190 }
191 err = mapForm(&wrongLoc, map[string][]string{"Time": {"2019-01-20T16:02:58Z"}})
192 assert.Error(t, err)
193
194
195 var wrongTime struct {
196 Time time.Time
197 }
198 err = mapForm(&wrongTime, map[string][]string{"Time": {"wrong"}})
199 assert.Error(t, err)
200 }
201
202 func TestMappingTimeDuration(t *testing.T) {
203 var s struct {
204 D time.Duration
205 }
206
207
208 err := mappingByPtr(&s, formSource{"D": {"5s"}}, "form")
209 assert.NoError(t, err)
210 assert.Equal(t, 5*time.Second, s.D)
211
212
213 err = mappingByPtr(&s, formSource{"D": {"wrong"}}, "form")
214 assert.Error(t, err)
215 }
216
217 func TestMappingSlice(t *testing.T) {
218 var s struct {
219 Slice []int `form:"slice,default=9"`
220 }
221
222
223 err := mappingByPtr(&s, formSource{}, "form")
224 assert.NoError(t, err)
225 assert.Equal(t, []int{9}, s.Slice)
226
227
228 err = mappingByPtr(&s, formSource{"slice": {"3", "4"}}, "form")
229 assert.NoError(t, err)
230 assert.Equal(t, []int{3, 4}, s.Slice)
231
232
233 err = mappingByPtr(&s, formSource{"slice": {"wrong"}}, "form")
234 assert.Error(t, err)
235 }
236
237 func TestMappingArray(t *testing.T) {
238 var s struct {
239 Array [2]int `form:"array,default=9"`
240 }
241
242
243 err := mappingByPtr(&s, formSource{}, "form")
244 assert.Error(t, err)
245
246
247 err = mappingByPtr(&s, formSource{"array": {"3", "4"}}, "form")
248 assert.NoError(t, err)
249 assert.Equal(t, [2]int{3, 4}, s.Array)
250
251
252 err = mappingByPtr(&s, formSource{"array": {"3"}}, "form")
253 assert.Error(t, err)
254
255
256 err = mappingByPtr(&s, formSource{"array": {"wrong"}}, "form")
257 assert.Error(t, err)
258 }
259
260 func TestMappingStructField(t *testing.T) {
261 var s struct {
262 J struct {
263 I int
264 }
265 }
266
267 err := mappingByPtr(&s, formSource{"J": {`{"I": 9}`}}, "form")
268 assert.NoError(t, err)
269 assert.Equal(t, 9, s.J.I)
270 }
271
272 func TestMappingMapField(t *testing.T) {
273 var s struct {
274 M map[string]int
275 }
276
277 err := mappingByPtr(&s, formSource{"M": {`{"one": 1}`}}, "form")
278 assert.NoError(t, err)
279 assert.Equal(t, map[string]int{"one": 1}, s.M)
280 }
281
282 func TestMappingIgnoredCircularRef(t *testing.T) {
283 type S struct {
284 S *S `form:"-"`
285 }
286 var s S
287
288 err := mappingByPtr(&s, formSource{}, "form")
289 assert.NoError(t, err)
290 }
291
View as plain text