1
2
3
4
5
6 package cast
7
8 import (
9 "encoding/json"
10 "errors"
11 "fmt"
12 "html/template"
13 "path"
14 "reflect"
15 "testing"
16 "time"
17
18 qt "github.com/frankban/quicktest"
19 )
20
21 type testStep struct {
22 input interface{}
23 expect interface{}
24 iserr bool
25 }
26
27 func createNumberTestSteps(zero, one, eight, eightnegative, eightpoint31, eightpoint31negative interface{}) []testStep {
28 var jeight, jminuseight, jfloateight json.Number
29 _ = json.Unmarshal([]byte("8"), &jeight)
30 _ = json.Unmarshal([]byte("-8"), &jminuseight)
31 _ = json.Unmarshal([]byte("8.0"), &jfloateight)
32
33 kind := reflect.TypeOf(zero).Kind()
34 isUint := kind == reflect.Uint || kind == reflect.Uint8 || kind == reflect.Uint16 || kind == reflect.Uint32 || kind == reflect.Uint64
35
36
37 eightpoint31_32 := eightpoint31
38 eightpoint31negative_32 := eightpoint31negative
39 if kind == reflect.Float64 {
40 eightpoint31_32 = float64(float32(eightpoint31.(float64)))
41 eightpoint31negative_32 = float64(float32(eightpoint31negative.(float64)))
42 }
43
44 return []testStep{
45 {int(8), eight, false},
46 {int8(8), eight, false},
47 {int16(8), eight, false},
48 {int32(8), eight, false},
49 {int64(8), eight, false},
50 {time.Weekday(8), eight, false},
51 {time.Month(8), eight, false},
52 {uint(8), eight, false},
53 {uint8(8), eight, false},
54 {uint16(8), eight, false},
55 {uint32(8), eight, false},
56 {uint64(8), eight, false},
57 {float32(8.31), eightpoint31_32, false},
58 {float64(8.31), eightpoint31, false},
59 {true, one, false},
60 {false, zero, false},
61 {"8", eight, false},
62 {nil, zero, false},
63 {int(-8), eightnegative, isUint},
64 {int8(-8), eightnegative, isUint},
65 {int16(-8), eightnegative, isUint},
66 {int32(-8), eightnegative, isUint},
67 {int64(-8), eightnegative, isUint},
68 {float32(-8.31), eightpoint31negative_32, isUint},
69 {float64(-8.31), eightpoint31negative, isUint},
70 {"-8", eightnegative, isUint},
71 {jeight, eight, false},
72 {jminuseight, eightnegative, isUint},
73 {jfloateight, eight, false},
74 {"test", zero, true},
75 {testing.T{}, zero, true},
76 }
77 }
78
79
80 func runNumberTest(c *qt.C, tests []testStep, tove func(interface{}) (interface{}, error), tov func(interface{}) interface{}) {
81 c.Helper()
82
83 for i, test := range tests {
84 errmsg := qt.Commentf("i = %d", i)
85
86 v, err := tove(test.input)
87 if test.iserr {
88 c.Assert(err, qt.IsNotNil, errmsg)
89 continue
90 }
91 c.Assert(err, qt.IsNil, errmsg)
92 c.Assert(v, qt.Equals, test.expect, errmsg)
93
94
95 v = tov(test.input)
96 c.Assert(v, qt.Equals, test.expect, errmsg)
97 }
98 }
99
100 func TestToUintE(t *testing.T) {
101 tests := createNumberTestSteps(uint(0), uint(1), uint(8), uint(0), uint(8), uint(8))
102
103 runNumberTest(
104 qt.New(t),
105 tests,
106 func(v interface{}) (interface{}, error) { return ToUintE(v) },
107 func(v interface{}) interface{} { return ToUint(v) },
108 )
109 }
110
111 func TestToUint64E(t *testing.T) {
112 tests := createNumberTestSteps(uint64(0), uint64(1), uint64(8), uint64(0), uint64(8), uint64(8))
113
114 runNumberTest(
115 qt.New(t),
116 tests,
117 func(v interface{}) (interface{}, error) { return ToUint64E(v) },
118 func(v interface{}) interface{} { return ToUint64(v) },
119 )
120 }
121
122 func TestToUint32E(t *testing.T) {
123 tests := createNumberTestSteps(uint32(0), uint32(1), uint32(8), uint32(0), uint32(8), uint32(8))
124
125 runNumberTest(
126 qt.New(t),
127 tests,
128 func(v interface{}) (interface{}, error) { return ToUint32E(v) },
129 func(v interface{}) interface{} { return ToUint32(v) },
130 )
131 }
132
133 func TestToUint16E(t *testing.T) {
134 tests := createNumberTestSteps(uint16(0), uint16(1), uint16(8), uint16(0), uint16(8), uint16(8))
135
136 runNumberTest(
137 qt.New(t),
138 tests,
139 func(v interface{}) (interface{}, error) { return ToUint16E(v) },
140 func(v interface{}) interface{} { return ToUint16(v) },
141 )
142 }
143
144 func TestToUint8E(t *testing.T) {
145 tests := createNumberTestSteps(uint8(0), uint8(1), uint8(8), uint8(0), uint8(8), uint8(8))
146
147 runNumberTest(
148 qt.New(t),
149 tests,
150 func(v interface{}) (interface{}, error) { return ToUint8E(v) },
151 func(v interface{}) interface{} { return ToUint8(v) },
152 )
153 }
154 func TestToIntE(t *testing.T) {
155 tests := createNumberTestSteps(int(0), int(1), int(8), int(-8), int(8), int(-8))
156
157 runNumberTest(
158 qt.New(t),
159 tests,
160 func(v interface{}) (interface{}, error) { return ToIntE(v) },
161 func(v interface{}) interface{} { return ToInt(v) },
162 )
163 }
164
165 func TestToInt64E(t *testing.T) {
166 tests := createNumberTestSteps(int64(0), int64(1), int64(8), int64(-8), int64(8), int64(-8))
167
168 runNumberTest(
169 qt.New(t),
170 tests,
171 func(v interface{}) (interface{}, error) { return ToInt64E(v) },
172 func(v interface{}) interface{} { return ToInt64(v) },
173 )
174 }
175
176 func TestToInt32E(t *testing.T) {
177 tests := createNumberTestSteps(int32(0), int32(1), int32(8), int32(-8), int32(8), int32(-8))
178
179 runNumberTest(
180 qt.New(t),
181 tests,
182 func(v interface{}) (interface{}, error) { return ToInt32E(v) },
183 func(v interface{}) interface{} { return ToInt32(v) },
184 )
185 }
186
187 func TestToInt16E(t *testing.T) {
188 tests := createNumberTestSteps(int16(0), int16(1), int16(8), int16(-8), int16(8), int16(-8))
189
190 runNumberTest(
191 qt.New(t),
192 tests,
193 func(v interface{}) (interface{}, error) { return ToInt16E(v) },
194 func(v interface{}) interface{} { return ToInt16(v) },
195 )
196 }
197
198 func TestToInt8E(t *testing.T) {
199 tests := createNumberTestSteps(int8(0), int8(1), int8(8), int8(-8), int8(8), int8(-8))
200
201 runNumberTest(
202 qt.New(t),
203 tests,
204 func(v interface{}) (interface{}, error) { return ToInt8E(v) },
205 func(v interface{}) interface{} { return ToInt8(v) },
206 )
207 }
208
209 func TestToFloat64E(t *testing.T) {
210 tests := createNumberTestSteps(float64(0), float64(1), float64(8), float64(-8), float64(8.31), float64(-8.31))
211
212 runNumberTest(
213 qt.New(t),
214 tests,
215 func(v interface{}) (interface{}, error) { return ToFloat64E(v) },
216 func(v interface{}) interface{} { return ToFloat64(v) },
217 )
218 }
219
220 func TestToFloat32E(t *testing.T) {
221 tests := createNumberTestSteps(float32(0), float32(1), float32(8), float32(-8), float32(8.31), float32(-8.31))
222
223 runNumberTest(
224 qt.New(t),
225 tests,
226 func(v interface{}) (interface{}, error) { return ToFloat32E(v) },
227 func(v interface{}) interface{} { return ToFloat32(v) },
228 )
229 }
230
231 func TestToStringE(t *testing.T) {
232 c := qt.New(t)
233
234 var jn json.Number
235 _ = json.Unmarshal([]byte("8"), &jn)
236 type Key struct {
237 k string
238 }
239 key := &Key{"foo"}
240
241 tests := []struct {
242 input interface{}
243 expect string
244 iserr bool
245 }{
246 {int(8), "8", false},
247 {int8(8), "8", false},
248 {int16(8), "8", false},
249 {int32(8), "8", false},
250 {int64(8), "8", false},
251 {uint(8), "8", false},
252 {uint8(8), "8", false},
253 {uint16(8), "8", false},
254 {uint32(8), "8", false},
255 {uint64(8), "8", false},
256 {float32(8.31), "8.31", false},
257 {float64(8.31), "8.31", false},
258 {jn, "8", false},
259 {true, "true", false},
260 {false, "false", false},
261 {nil, "", false},
262 {[]byte("one time"), "one time", false},
263 {"one more time", "one more time", false},
264 {template.HTML("one time"), "one time", false},
265 {template.URL("http://somehost.foo"), "http://somehost.foo", false},
266 {template.JS("(1+2)"), "(1+2)", false},
267 {template.CSS("a"), "a", false},
268 {template.HTMLAttr("a"), "a", false},
269
270 {testing.T{}, "", true},
271 {key, "", true},
272 }
273
274 for i, test := range tests {
275 errmsg := qt.Commentf("i = %d", i)
276
277 v, err := ToStringE(test.input)
278 if test.iserr {
279 c.Assert(err, qt.IsNotNil, errmsg)
280 continue
281 }
282
283 c.Assert(err, qt.IsNil, errmsg)
284 c.Assert(v, qt.Equals, test.expect, errmsg)
285
286
287 v = ToString(test.input)
288 c.Assert(v, qt.Equals, test.expect, errmsg)
289 }
290 }
291
292 type foo struct {
293 val string
294 }
295
296 func (x foo) String() string {
297 return x.val
298 }
299
300 func TestStringerToString(t *testing.T) {
301 c := qt.New(t)
302
303 var x foo
304 x.val = "bar"
305 c.Assert(ToString(x), qt.Equals, "bar")
306 }
307
308 type fu struct {
309 val string
310 }
311
312 func (x fu) Error() string {
313 return x.val
314 }
315
316 func TestErrorToString(t *testing.T) {
317 c := qt.New(t)
318
319 var x fu
320 x.val = "bar"
321 c.Assert(ToString(x), qt.Equals, "bar")
322 }
323
324 func TestStringMapStringSliceE(t *testing.T) {
325 c := qt.New(t)
326
327
328 var stringMapString = map[string]string{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
329 var stringMapInterface = map[string]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
330 var interfaceMapString = map[interface{}]string{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
331 var interfaceMapInterface = map[interface{}]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
332
333
334 var stringMapStringSlice = map[string][]string{"key 1": {"value 1", "value 2", "value 3"}, "key 2": {"value 1", "value 2", "value 3"}, "key 3": {"value 1", "value 2", "value 3"}}
335 var stringMapInterfaceSlice = map[string][]interface{}{"key 1": {"value 1", "value 2", "value 3"}, "key 2": {"value 1", "value 2", "value 3"}, "key 3": {"value 1", "value 2", "value 3"}}
336 var stringMapInterfaceInterfaceSlice = map[string]interface{}{"key 1": []interface{}{"value 1", "value 2", "value 3"}, "key 2": []interface{}{"value 1", "value 2", "value 3"}, "key 3": []interface{}{"value 1", "value 2", "value 3"}}
337 var stringMapStringSingleSliceFieldsResult = map[string][]string{"key 1": {"value", "1"}, "key 2": {"value", "2"}, "key 3": {"value", "3"}}
338 var interfaceMapStringSlice = map[interface{}][]string{"key 1": {"value 1", "value 2", "value 3"}, "key 2": {"value 1", "value 2", "value 3"}, "key 3": {"value 1", "value 2", "value 3"}}
339 var interfaceMapInterfaceSlice = map[interface{}][]interface{}{"key 1": {"value 1", "value 2", "value 3"}, "key 2": {"value 1", "value 2", "value 3"}, "key 3": {"value 1", "value 2", "value 3"}}
340
341 var stringMapStringSliceMultiple = map[string][]string{"key 1": {"value 1", "value 2", "value 3"}, "key 2": {"value 1", "value 2", "value 3"}, "key 3": {"value 1", "value 2", "value 3"}}
342 var stringMapStringSliceSingle = map[string][]string{"key 1": {"value 1"}, "key 2": {"value 2"}, "key 3": {"value 3"}}
343
344 var stringMapInterface1 = map[string]interface{}{"key 1": []string{"value 1"}, "key 2": []string{"value 2"}}
345 var stringMapInterfaceResult1 = map[string][]string{"key 1": {"value 1"}, "key 2": {"value 2"}}
346
347 var jsonStringMapString = `{"key 1": "value 1", "key 2": "value 2"}`
348 var jsonStringMapStringArray = `{"key 1": ["value 1"], "key 2": ["value 2", "value 3"]}`
349 var jsonStringMapStringArrayResult = map[string][]string{"key 1": {"value 1"}, "key 2": {"value 2", "value 3"}}
350
351 type Key struct {
352 k string
353 }
354
355 tests := []struct {
356 input interface{}
357 expect map[string][]string
358 iserr bool
359 }{
360 {stringMapStringSlice, stringMapStringSlice, false},
361 {stringMapInterfaceSlice, stringMapStringSlice, false},
362 {stringMapInterfaceInterfaceSlice, stringMapStringSlice, false},
363 {stringMapStringSliceMultiple, stringMapStringSlice, false},
364 {stringMapStringSliceMultiple, stringMapStringSlice, false},
365 {stringMapString, stringMapStringSliceSingle, false},
366 {stringMapInterface, stringMapStringSliceSingle, false},
367 {stringMapInterface1, stringMapInterfaceResult1, false},
368 {interfaceMapStringSlice, stringMapStringSlice, false},
369 {interfaceMapInterfaceSlice, stringMapStringSlice, false},
370 {interfaceMapString, stringMapStringSingleSliceFieldsResult, false},
371 {interfaceMapInterface, stringMapStringSingleSliceFieldsResult, false},
372 {jsonStringMapStringArray, jsonStringMapStringArrayResult, false},
373
374
375 {nil, nil, true},
376 {testing.T{}, nil, true},
377 {map[interface{}]interface{}{"foo": testing.T{}}, nil, true},
378 {map[interface{}]interface{}{Key{"foo"}: "bar"}, nil, true},
379 {jsonStringMapString, nil, true},
380 {"", nil, true},
381 }
382
383 for i, test := range tests {
384 errmsg := qt.Commentf("i = %d", i)
385
386 v, err := ToStringMapStringSliceE(test.input)
387 if test.iserr {
388 c.Assert(err, qt.IsNotNil, errmsg)
389 continue
390 }
391
392 c.Assert(err, qt.IsNil, errmsg)
393 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
394
395
396 v = ToStringMapStringSlice(test.input)
397 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
398 }
399 }
400
401 func TestToStringMapE(t *testing.T) {
402 c := qt.New(t)
403
404 tests := []struct {
405 input interface{}
406 expect map[string]interface{}
407 iserr bool
408 }{
409 {map[interface{}]interface{}{"tag": "tags", "group": "groups"}, map[string]interface{}{"tag": "tags", "group": "groups"}, false},
410 {map[string]interface{}{"tag": "tags", "group": "groups"}, map[string]interface{}{"tag": "tags", "group": "groups"}, false},
411 {`{"tag": "tags", "group": "groups"}`, map[string]interface{}{"tag": "tags", "group": "groups"}, false},
412 {`{"tag": "tags", "group": true}`, map[string]interface{}{"tag": "tags", "group": true}, false},
413
414
415 {nil, nil, true},
416 {testing.T{}, nil, true},
417 {"", nil, true},
418 }
419
420 for i, test := range tests {
421 errmsg := qt.Commentf("i = %d", i)
422
423 v, err := ToStringMapE(test.input)
424 if test.iserr {
425 c.Assert(err, qt.IsNotNil, errmsg)
426 continue
427 }
428
429 c.Assert(err, qt.IsNil, errmsg)
430 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
431
432
433 v = ToStringMap(test.input)
434 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
435 }
436 }
437
438 func TestToStringMapBoolE(t *testing.T) {
439 c := qt.New(t)
440
441 tests := []struct {
442 input interface{}
443 expect map[string]bool
444 iserr bool
445 }{
446 {map[interface{}]interface{}{"v1": true, "v2": false}, map[string]bool{"v1": true, "v2": false}, false},
447 {map[string]interface{}{"v1": true, "v2": false}, map[string]bool{"v1": true, "v2": false}, false},
448 {map[string]bool{"v1": true, "v2": false}, map[string]bool{"v1": true, "v2": false}, false},
449 {`{"v1": true, "v2": false}`, map[string]bool{"v1": true, "v2": false}, false},
450
451
452 {nil, nil, true},
453 {testing.T{}, nil, true},
454 {"", nil, true},
455 }
456
457 for i, test := range tests {
458 errmsg := qt.Commentf("i = %d", i)
459
460 v, err := ToStringMapBoolE(test.input)
461 if test.iserr {
462 c.Assert(err, qt.IsNotNil, errmsg)
463 continue
464 }
465
466 c.Assert(err, qt.IsNil, errmsg)
467 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
468
469
470 v = ToStringMapBool(test.input)
471 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
472 }
473 }
474
475 func TestToStringMapIntE(t *testing.T) {
476 c := qt.New(t)
477
478 tests := []struct {
479 input interface{}
480 expect map[string]int
481 iserr bool
482 }{
483 {map[interface{}]interface{}{"v1": 1, "v2": 222}, map[string]int{"v1": 1, "v2": 222}, false},
484 {map[string]interface{}{"v1": 342, "v2": 5141}, map[string]int{"v1": 342, "v2": 5141}, false},
485 {map[string]int{"v1": 33, "v2": 88}, map[string]int{"v1": 33, "v2": 88}, false},
486 {map[string]int32{"v1": int32(33), "v2": int32(88)}, map[string]int{"v1": 33, "v2": 88}, false},
487 {map[string]uint16{"v1": uint16(33), "v2": uint16(88)}, map[string]int{"v1": 33, "v2": 88}, false},
488 {map[string]float64{"v1": float64(8.22), "v2": float64(43.32)}, map[string]int{"v1": 8, "v2": 43}, false},
489 {`{"v1": 67, "v2": 56}`, map[string]int{"v1": 67, "v2": 56}, false},
490
491
492 {nil, nil, true},
493 {testing.T{}, nil, true},
494 {"", nil, true},
495 }
496
497 for i, test := range tests {
498 errmsg := qt.Commentf("i = %d", i)
499
500 v, err := ToStringMapIntE(test.input)
501 if test.iserr {
502 c.Assert(err, qt.IsNotNil, errmsg)
503 continue
504 }
505
506 c.Assert(err, qt.IsNil, errmsg)
507 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
508
509
510 v = ToStringMapInt(test.input)
511 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
512 }
513 }
514
515 func TestToStringMapInt64E(t *testing.T) {
516 c := qt.New(t)
517
518 tests := []struct {
519 input interface{}
520 expect map[string]int64
521 iserr bool
522 }{
523 {map[interface{}]interface{}{"v1": int32(8), "v2": int32(888)}, map[string]int64{"v1": int64(8), "v2": int64(888)}, false},
524 {map[string]interface{}{"v1": int64(45), "v2": int64(67)}, map[string]int64{"v1": 45, "v2": 67}, false},
525 {map[string]int64{"v1": 33, "v2": 88}, map[string]int64{"v1": 33, "v2": 88}, false},
526 {map[string]int{"v1": 33, "v2": 88}, map[string]int64{"v1": 33, "v2": 88}, false},
527 {map[string]int32{"v1": int32(33), "v2": int32(88)}, map[string]int64{"v1": 33, "v2": 88}, false},
528 {map[string]uint16{"v1": uint16(33), "v2": uint16(88)}, map[string]int64{"v1": 33, "v2": 88}, false},
529 {map[string]float64{"v1": float64(8.22), "v2": float64(43.32)}, map[string]int64{"v1": 8, "v2": 43}, false},
530 {`{"v1": 67, "v2": 56}`, map[string]int64{"v1": 67, "v2": 56}, false},
531
532
533 {nil, nil, true},
534 {testing.T{}, nil, true},
535 {"", nil, true},
536 }
537
538 for i, test := range tests {
539 errmsg := qt.Commentf("i = %d", i)
540
541 v, err := ToStringMapInt64E(test.input)
542 if test.iserr {
543 c.Assert(err, qt.IsNotNil)
544 continue
545 }
546
547 c.Assert(err, qt.IsNil)
548 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
549
550
551 v = ToStringMapInt64(test.input)
552 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
553 }
554 }
555
556 func TestToStringMapStringE(t *testing.T) {
557 c := qt.New(t)
558
559 var stringMapString = map[string]string{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
560 var stringMapInterface = map[string]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
561 var interfaceMapString = map[interface{}]string{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
562 var interfaceMapInterface = map[interface{}]interface{}{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}
563 var jsonString = `{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"}`
564 var invalidJsonString = `{"key 1": "value 1", "key 2": "value 2", "key 3": "value 3"`
565 var emptyString = ""
566
567 tests := []struct {
568 input interface{}
569 expect map[string]string
570 iserr bool
571 }{
572 {stringMapString, stringMapString, false},
573 {stringMapInterface, stringMapString, false},
574 {interfaceMapString, stringMapString, false},
575 {interfaceMapInterface, stringMapString, false},
576 {jsonString, stringMapString, false},
577
578
579 {nil, nil, true},
580 {testing.T{}, nil, true},
581 {invalidJsonString, nil, true},
582 {emptyString, nil, true},
583 }
584
585 for i, test := range tests {
586 errmsg := qt.Commentf("i = %d", i)
587
588 v, err := ToStringMapStringE(test.input)
589 if test.iserr {
590 c.Assert(err, qt.IsNotNil)
591 continue
592 }
593
594 c.Assert(err, qt.IsNil)
595 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
596
597
598 v = ToStringMapString(test.input)
599 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
600 }
601 }
602
603 func TestToBoolSliceE(t *testing.T) {
604 c := qt.New(t)
605
606 tests := []struct {
607 input interface{}
608 expect []bool
609 iserr bool
610 }{
611 {[]bool{true, false, true}, []bool{true, false, true}, false},
612 {[]interface{}{true, false, true}, []bool{true, false, true}, false},
613 {[]int{1, 0, 1}, []bool{true, false, true}, false},
614 {[]string{"true", "false", "true"}, []bool{true, false, true}, false},
615
616 {nil, nil, true},
617 {testing.T{}, nil, true},
618 {[]string{"foo", "bar"}, nil, true},
619 }
620
621 for i, test := range tests {
622 errmsg := qt.Commentf("i = %d", i)
623
624 v, err := ToBoolSliceE(test.input)
625 if test.iserr {
626 c.Assert(err, qt.IsNotNil)
627 continue
628 }
629
630 c.Assert(err, qt.IsNil)
631 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
632
633
634 v = ToBoolSlice(test.input)
635 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
636 }
637 }
638
639 func TestToIntSliceE(t *testing.T) {
640 c := qt.New(t)
641
642 tests := []struct {
643 input interface{}
644 expect []int
645 iserr bool
646 }{
647 {[]int{1, 3}, []int{1, 3}, false},
648 {[]interface{}{1.2, 3.2}, []int{1, 3}, false},
649 {[]string{"2", "3"}, []int{2, 3}, false},
650 {[2]string{"2", "3"}, []int{2, 3}, false},
651
652 {nil, nil, true},
653 {testing.T{}, nil, true},
654 {[]string{"foo", "bar"}, nil, true},
655 }
656
657 for i, test := range tests {
658 errmsg := qt.Commentf("i = %d", i)
659
660 v, err := ToIntSliceE(test.input)
661 if test.iserr {
662 c.Assert(err, qt.IsNotNil)
663 continue
664 }
665
666 c.Assert(err, qt.IsNil)
667 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
668
669
670 v = ToIntSlice(test.input)
671 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
672 }
673 }
674
675 func TestToSliceE(t *testing.T) {
676 c := qt.New(t)
677
678 tests := []struct {
679 input interface{}
680 expect []interface{}
681 iserr bool
682 }{
683 {[]interface{}{1, 3}, []interface{}{1, 3}, false},
684 {[]map[string]interface{}{{"k1": 1}, {"k2": 2}}, []interface{}{map[string]interface{}{"k1": 1}, map[string]interface{}{"k2": 2}}, false},
685
686 {nil, nil, true},
687 {testing.T{}, nil, true},
688 }
689
690 for i, test := range tests {
691 errmsg := qt.Commentf("i = %d", i)
692
693 v, err := ToSliceE(test.input)
694 if test.iserr {
695 c.Assert(err, qt.IsNotNil)
696 continue
697 }
698
699 c.Assert(err, qt.IsNil)
700 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
701
702
703 v = ToSlice(test.input)
704 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
705 }
706 }
707
708 func TestToStringSliceE(t *testing.T) {
709 c := qt.New(t)
710
711 tests := []struct {
712 input interface{}
713 expect []string
714 iserr bool
715 }{
716 {[]int{1, 2}, []string{"1", "2"}, false},
717 {[]int8{int8(1), int8(2)}, []string{"1", "2"}, false},
718 {[]int32{int32(1), int32(2)}, []string{"1", "2"}, false},
719 {[]int64{int64(1), int64(2)}, []string{"1", "2"}, false},
720 {[]float32{float32(1.01), float32(2.01)}, []string{"1.01", "2.01"}, false},
721 {[]float64{float64(1.01), float64(2.01)}, []string{"1.01", "2.01"}, false},
722 {[]string{"a", "b"}, []string{"a", "b"}, false},
723 {[]interface{}{1, 3}, []string{"1", "3"}, false},
724 {interface{}(1), []string{"1"}, false},
725 {[]error{errors.New("a"), errors.New("b")}, []string{"a", "b"}, false},
726
727 {nil, nil, true},
728 {testing.T{}, nil, true},
729 }
730
731 for i, test := range tests {
732 errmsg := qt.Commentf("i = %d", i)
733
734 v, err := ToStringSliceE(test.input)
735 if test.iserr {
736 c.Assert(err, qt.IsNotNil)
737 continue
738 }
739
740 c.Assert(err, qt.IsNil)
741 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
742
743
744 v = ToStringSlice(test.input)
745 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
746 }
747 }
748
749 func TestToDurationSliceE(t *testing.T) {
750 c := qt.New(t)
751
752 tests := []struct {
753 input interface{}
754 expect []time.Duration
755 iserr bool
756 }{
757 {[]string{"1s", "1m"}, []time.Duration{time.Second, time.Minute}, false},
758 {[]int{1, 2}, []time.Duration{1, 2}, false},
759 {[]interface{}{1, 3}, []time.Duration{1, 3}, false},
760 {[]time.Duration{1, 3}, []time.Duration{1, 3}, false},
761
762
763 {nil, nil, true},
764 {testing.T{}, nil, true},
765 {[]string{"invalid"}, nil, true},
766 }
767
768 for i, test := range tests {
769 errmsg := qt.Commentf("i = %d", i)
770
771 v, err := ToDurationSliceE(test.input)
772 if test.iserr {
773 c.Assert(err, qt.IsNotNil)
774 continue
775 }
776
777 c.Assert(err, qt.IsNil)
778 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
779
780
781 v = ToDurationSlice(test.input)
782 c.Assert(v, qt.DeepEquals, test.expect, errmsg)
783 }
784 }
785
786 func TestToBoolE(t *testing.T) {
787 c := qt.New(t)
788
789 var jf, jt, je json.Number
790 _ = json.Unmarshal([]byte("0"), &jf)
791 _ = json.Unmarshal([]byte("1"), &jt)
792 _ = json.Unmarshal([]byte("1.0"), &je)
793 tests := []struct {
794 input interface{}
795 expect bool
796 iserr bool
797 }{
798 {0, false, false},
799 {int64(0), false, false},
800 {int32(0), false, false},
801 {int16(0), false, false},
802 {int8(0), false, false},
803 {uint(0), false, false},
804 {uint64(0), false, false},
805 {uint32(0), false, false},
806 {uint16(0), false, false},
807 {uint8(0), false, false},
808 {float64(0), false, false},
809 {float32(0), false, false},
810 {time.Duration(0), false, false},
811 {jf, false, false},
812 {nil, false, false},
813 {"false", false, false},
814 {"FALSE", false, false},
815 {"False", false, false},
816 {"f", false, false},
817 {"F", false, false},
818 {false, false, false},
819
820 {"true", true, false},
821 {"TRUE", true, false},
822 {"True", true, false},
823 {"t", true, false},
824 {"T", true, false},
825 {1, true, false},
826 {int64(1), true, false},
827 {int32(1), true, false},
828 {int16(1), true, false},
829 {int8(1), true, false},
830 {uint(1), true, false},
831 {uint64(1), true, false},
832 {uint32(1), true, false},
833 {uint16(1), true, false},
834 {uint8(1), true, false},
835 {float64(1), true, false},
836 {float32(1), true, false},
837 {time.Duration(1), true, false},
838 {jt, true, false},
839 {je, true, false},
840 {true, true, false},
841 {-1, true, false},
842 {int64(-1), true, false},
843 {int32(-1), true, false},
844 {int16(-1), true, false},
845 {int8(-1), true, false},
846
847
848 {"test", false, true},
849 {testing.T{}, false, true},
850 }
851
852 for i, test := range tests {
853 errmsg := qt.Commentf("i = %d", i)
854
855 v, err := ToBoolE(test.input)
856 if test.iserr {
857 c.Assert(err, qt.IsNotNil)
858 continue
859 }
860
861 c.Assert(err, qt.IsNil)
862 c.Assert(v, qt.Equals, test.expect, errmsg)
863
864
865 v = ToBool(test.input)
866 c.Assert(v, qt.Equals, test.expect, errmsg)
867 }
868 }
869
870 func BenchmarkTooBool(b *testing.B) {
871 for i := 0; i < b.N; i++ {
872 if !ToBool(true) {
873 b.Fatal("ToBool returned false")
874 }
875 }
876 }
877
878 func BenchmarkTooInt(b *testing.B) {
879 convert := func(num52 interface{}) {
880 if v := ToInt(num52); v != 52 {
881 b.Fatalf("ToInt returned wrong value, got %d, want %d", v, 32)
882 }
883 }
884 for i := 0; i < b.N; i++ {
885 convert("52")
886 convert(52.0)
887 convert(uint64(52))
888 }
889 }
890
891 func BenchmarkTrimZeroDecimal(b *testing.B) {
892 for i := 0; i < b.N; i++ {
893 trimZeroDecimal("")
894 trimZeroDecimal("123")
895 trimZeroDecimal("120")
896 trimZeroDecimal("120.00")
897 }
898 }
899
900 func BenchmarkCommonTimeLayouts(b *testing.B) {
901 for i := 0; i < b.N; i++ {
902 for _, commonLayout := range []string{"2019-04-29", "2017-05-30T00:00:00Z"} {
903 _, err := StringToDateInDefaultLocation(commonLayout, time.UTC)
904 if err != nil {
905 b.Fatal(err)
906 }
907 }
908 }
909 }
910
911 func TestIndirectPointers(t *testing.T) {
912 c := qt.New(t)
913
914 x := 13
915 y := &x
916 z := &y
917
918 c.Assert(ToInt(y), qt.Equals, 13)
919 c.Assert(ToInt(z), qt.Equals, 13)
920
921 }
922
923 func TestToTime(t *testing.T) {
924 c := qt.New(t)
925
926 var jntime, jnetime json.Number
927 _ = json.Unmarshal([]byte("1234567890"), &jntime)
928 _ = json.Unmarshal([]byte("123.4567890"), &jnetime)
929 tests := []struct {
930 input interface{}
931 expect time.Time
932 iserr bool
933 }{
934 {"2009-11-10 23:00:00 +0000 UTC", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false},
935 {"Tue Nov 10 23:00:00 2009", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false},
936 {"Tue Nov 10 23:00:00 UTC 2009", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false},
937 {"Tue Nov 10 23:00:00 +0000 2009", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false},
938 {"10 Nov 09 23:00 UTC", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false},
939 {"10 Nov 09 23:00 +0000", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false},
940 {"Tuesday, 10-Nov-09 23:00:00 UTC", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false},
941 {"Tue, 10 Nov 2009 23:00:00 UTC", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false},
942 {"Tue, 10 Nov 2009 23:00:00 +0000", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false},
943 {"2009-11-10T23:00:00Z", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false},
944 {"2018-10-21T23:21:29+0200", time.Date(2018, 10, 21, 21, 21, 29, 0, time.UTC), false},
945 {"2009-11-10T23:00:00Z", time.Date(2009, 11, 10, 23, 0, 0, 0, time.UTC), false},
946 {"11:00PM", time.Date(0, 1, 1, 23, 0, 0, 0, time.UTC), false},
947 {"Nov 10 23:00:00", time.Date(0, 11, 10, 23, 0, 0, 0, time.UTC), false},
948 {"Nov 10 23:00:00.000", time.Date(0, 11, 10, 23, 0, 0, 0, time.UTC), false},
949 {"Nov 10 23:00:00.000000", time.Date(0, 11, 10, 23, 0, 0, 0, time.UTC), false},
950 {"Nov 10 23:00:00.000000000", time.Date(0, 11, 10, 23, 0, 0, 0, time.UTC), false},
951 {"2016-03-06 15:28:01-00:00", time.Date(2016, 3, 6, 15, 28, 1, 0, time.UTC), false},
952 {"2016-03-06 15:28:01-0000", time.Date(2016, 3, 6, 15, 28, 1, 0, time.UTC), false},
953 {"2016-03-06 15:28:01", time.Date(2016, 3, 6, 15, 28, 1, 0, time.UTC), false},
954 {"2016-03-06 15:28:01 -0000", time.Date(2016, 3, 6, 15, 28, 1, 0, time.UTC), false},
955 {"2016-03-06 15:28:01 -00:00", time.Date(2016, 3, 6, 15, 28, 1, 0, time.UTC), false},
956 {"2016-03-06 15:28:01 +0900", time.Date(2016, 3, 6, 6, 28, 1, 0, time.UTC), false},
957 {"2016-03-06 15:28:01 +09:00", time.Date(2016, 3, 6, 6, 28, 1, 0, time.UTC), false},
958 {"2006-01-02", time.Date(2006, 1, 2, 0, 0, 0, 0, time.UTC), false},
959 {"02 Jan 2006", time.Date(2006, 1, 2, 0, 0, 0, 0, time.UTC), false},
960 {1472574600, time.Date(2016, 8, 30, 16, 30, 0, 0, time.UTC), false},
961 {int(1482597504), time.Date(2016, 12, 24, 16, 38, 24, 0, time.UTC), false},
962 {int64(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
963 {int32(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
964 {uint(1482597504), time.Date(2016, 12, 24, 16, 38, 24, 0, time.UTC), false},
965 {uint64(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
966 {uint32(1234567890), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
967 {jntime, time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
968 {time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), time.Date(2009, 2, 13, 23, 31, 30, 0, time.UTC), false},
969
970 {"2006", time.Time{}, true},
971 {jnetime, time.Time{}, true},
972 {testing.T{}, time.Time{}, true},
973 }
974
975 for i, test := range tests {
976 errmsg := qt.Commentf("i = %d", i)
977
978 v, err := ToTimeE(test.input)
979 if test.iserr {
980 c.Assert(err, qt.IsNotNil)
981 continue
982 }
983
984 c.Assert(err, qt.IsNil)
985 c.Assert(v.UTC(), qt.Equals, test.expect, errmsg)
986
987
988 v = ToTime(test.input)
989 c.Assert(v.UTC(), qt.Equals, test.expect, errmsg)
990 }
991 }
992
993 func TestToDurationE(t *testing.T) {
994 c := qt.New(t)
995
996 var td time.Duration = 5
997 var jn json.Number
998 _ = json.Unmarshal([]byte("5"), &jn)
999
1000 tests := []struct {
1001 input interface{}
1002 expect time.Duration
1003 iserr bool
1004 }{
1005 {time.Duration(5), td, false},
1006 {int(5), td, false},
1007 {int64(5), td, false},
1008 {int32(5), td, false},
1009 {int16(5), td, false},
1010 {int8(5), td, false},
1011 {uint(5), td, false},
1012 {uint64(5), td, false},
1013 {uint32(5), td, false},
1014 {uint16(5), td, false},
1015 {uint8(5), td, false},
1016 {float64(5), td, false},
1017 {float32(5), td, false},
1018 {jn, td, false},
1019 {string("5"), td, false},
1020 {string("5ns"), td, false},
1021 {string("5us"), time.Microsecond * td, false},
1022 {string("5µs"), time.Microsecond * td, false},
1023 {string("5ms"), time.Millisecond * td, false},
1024 {string("5s"), time.Second * td, false},
1025 {string("5m"), time.Minute * td, false},
1026 {string("5h"), time.Hour * td, false},
1027
1028 {"test", 0, true},
1029 {testing.T{}, 0, true},
1030 }
1031
1032 for i, test := range tests {
1033 errmsg := qt.Commentf("i = %d", i)
1034
1035 v, err := ToDurationE(test.input)
1036 if test.iserr {
1037 c.Assert(err, qt.IsNotNil)
1038 continue
1039 }
1040
1041 c.Assert(err, qt.IsNil)
1042 c.Assert(v, qt.Equals, test.expect, errmsg)
1043
1044
1045 v = ToDuration(test.input)
1046 c.Assert(v, qt.Equals, test.expect, errmsg)
1047 }
1048 }
1049
1050 func TestToTimeWithTimezones(t *testing.T) {
1051 c := qt.New(t)
1052
1053 est, err := time.LoadLocation("EST")
1054 c.Assert(err, qt.IsNil)
1055
1056 irn, err := time.LoadLocation("Iran")
1057 c.Assert(err, qt.IsNil)
1058
1059 swd, err := time.LoadLocation("Europe/Stockholm")
1060 c.Assert(err, qt.IsNil)
1061
1062
1063 utc2016 := time.Date(2016, time.January, 1, 0, 0, 0, 0, time.UTC)
1064 est2016 := time.Date(2016, time.January, 1, 0, 0, 0, 0, est)
1065 irn2016 := time.Date(2016, time.January, 1, 0, 0, 0, 0, irn)
1066 swd2016 := time.Date(2016, time.January, 1, 0, 0, 0, 0, swd)
1067 loc2016 := time.Date(2016, time.January, 1, 0, 0, 0, 0, time.Local)
1068
1069 for i, format := range timeFormats {
1070 format := format
1071 if format.typ == timeFormatTimeOnly {
1072 continue
1073 }
1074
1075 nameBase := fmt.Sprintf("%d;timeFormatType=%d;%s", i, format.typ, format.format)
1076
1077 t.Run(path.Join(nameBase), func(t *testing.T) {
1078 est2016str := est2016.Format(format.format)
1079 swd2016str := swd2016.Format(format.format)
1080
1081 t.Run("without default location", func(t *testing.T) {
1082 c := qt.New(t)
1083 converted, err := ToTimeE(est2016str)
1084 c.Assert(err, qt.IsNil)
1085 if format.hasTimezone() {
1086
1087 assertTimeEqual(t, est2016, converted)
1088 assertLocationEqual(t, est, converted.Location())
1089 } else {
1090
1091
1092 assertTimeEqual(t, utc2016, converted)
1093 assertLocationEqual(t, time.UTC, converted.Location())
1094 }
1095 })
1096
1097 t.Run("local timezone without a default location", func(t *testing.T) {
1098 c := qt.New(t)
1099 converted, err := ToTimeE(swd2016str)
1100 c.Assert(err, qt.IsNil)
1101 if format.hasTimezone() {
1102
1103 assertTimeEqual(t, swd2016, converted)
1104 assertLocationEqual(t, swd, converted.Location())
1105 } else {
1106
1107
1108 assertTimeEqual(t, utc2016, converted)
1109 assertLocationEqual(t, time.UTC, converted.Location())
1110 }
1111 })
1112
1113 t.Run("nil default location", func(t *testing.T) {
1114 c := qt.New(t)
1115
1116 converted, err := ToTimeInDefaultLocationE(est2016str, nil)
1117 c.Assert(err, qt.IsNil)
1118 if format.hasTimezone() {
1119
1120 assertTimeEqual(t, est2016, converted)
1121 assertLocationEqual(t, est, converted.Location())
1122 } else {
1123
1124
1125 assertTimeEqual(t, loc2016, converted)
1126 assertLocationEqual(t, time.Local, converted.Location())
1127 }
1128
1129 })
1130
1131 t.Run("default location not UTC", func(t *testing.T) {
1132 c := qt.New(t)
1133
1134 converted, err := ToTimeInDefaultLocationE(est2016str, irn)
1135 c.Assert(err, qt.IsNil)
1136 if format.hasTimezone() {
1137
1138 assertTimeEqual(t, est2016, converted)
1139 assertLocationEqual(t, est, converted.Location())
1140 } else {
1141
1142
1143 assertTimeEqual(t, irn2016, converted)
1144 assertLocationEqual(t, irn, converted.Location())
1145 }
1146
1147 })
1148
1149 t.Run("time in the local timezone default location not UTC", func(t *testing.T) {
1150 c := qt.New(t)
1151
1152 converted, err := ToTimeInDefaultLocationE(swd2016str, irn)
1153 c.Assert(err, qt.IsNil)
1154 if format.hasTimezone() {
1155
1156 assertTimeEqual(t, swd2016, converted)
1157 assertLocationEqual(t, swd, converted.Location())
1158 } else {
1159
1160
1161 assertTimeEqual(t, irn2016, converted)
1162 assertLocationEqual(t, irn, converted.Location())
1163 }
1164
1165 })
1166
1167 })
1168
1169 }
1170 }
1171
1172 func TestTrimZeroDecimal(t *testing.T) {
1173 c := qt.New(t)
1174
1175 c.Assert(trimZeroDecimal("10.0"), qt.Equals, "10")
1176 c.Assert(trimZeroDecimal("10.00"), qt.Equals, "10")
1177 c.Assert(trimZeroDecimal("10.010"), qt.Equals, "10.010")
1178 c.Assert(trimZeroDecimal("0.0000000000"), qt.Equals, "0")
1179 c.Assert(trimZeroDecimal("0.00000000001"), qt.Equals, "0.00000000001")
1180
1181 }
1182
1183 func assertTimeEqual(t *testing.T, expected, actual time.Time) {
1184 t.Helper()
1185
1186
1187 qt.Assert(t, actual.Format(time.RFC1123Z), qt.Equals, expected.Format(time.RFC1123Z))
1188 }
1189
1190 func assertLocationEqual(t *testing.T, expected, actual *time.Location) {
1191 t.Helper()
1192 qt.Assert(t, locationEqual(expected, actual), qt.IsTrue)
1193 }
1194
1195 func locationEqual(a, b *time.Location) bool {
1196
1197
1198
1199
1200
1201
1202
1203 if a == b {
1204 return true
1205 } else if a == nil || b == nil {
1206 return false
1207 }
1208
1209
1210
1211
1212 tA, err := time.ParseInLocation("2006-01-02", "2016-01-01", a)
1213 if err != nil {
1214 return false
1215 }
1216
1217 tB, err := time.ParseInLocation("2006-01-02", "2016-01-01", b)
1218 if err != nil {
1219 return false
1220 }
1221
1222 return tA.Equal(tB)
1223 }
1224
View as plain text