1// Copyright 2015 go-swagger maintainers
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package swag
16
17import (
18	"reflect"
19	"testing"
20	"time"
21
22	"github.com/stretchr/testify/assert"
23)
24
25func assertSingleValue(t *testing.T, inElem, elem reflect.Value, expectPointer bool, idx int) {
26	if !assert.Truef(t,
27		(elem.Kind() == reflect.Ptr) == expectPointer,
28		"Unexpected expectPointer=%t value type", expectPointer) {
29		return
30	}
31	if inElem.Kind() == reflect.Ptr && !inElem.IsNil() {
32		inElem = reflect.Indirect(inElem)
33	}
34	if elem.Kind() == reflect.Ptr && !elem.IsNil() {
35		elem = reflect.Indirect(elem)
36	}
37
38	if !assert.Truef(t,
39		(elem.Kind() == reflect.Ptr && elem.IsNil()) || IsZero(elem.Interface()) ==
40			(inElem.Kind() == reflect.Ptr && inElem.IsNil()) || IsZero(inElem.Interface()),
41		"Unexpected nil pointer at idx %d", idx) {
42		return
43	}
44
45	if !((elem.Kind() == reflect.Ptr && elem.IsNil()) || IsZero(elem.Interface())) {
46		if !assert.IsTypef(t, inElem.Interface(), elem.Interface(), "Expected in/out to match types") {
47			return
48		}
49		assert.EqualValuesf(t, inElem.Interface(), elem.Interface(), "Unexpected value at idx %d: %v", idx, elem.Interface())
50	}
51}
52
53// assertValues checks equivalent representation pointer vs values for single var, slices and maps
54func assertValues(t *testing.T, in, out interface{}, expectPointer bool, idx int) {
55	vin := reflect.ValueOf(in)
56	vout := reflect.ValueOf(out)
57	switch vin.Kind() {
58	case reflect.Slice, reflect.Map:
59		if !assert.Equalf(t, vin.Kind(), vout.Kind(), "Unexpected output type at idx %d", idx) ||
60			!assert.Equalf(t, vin.Len(), vout.Len(), "Unexpected len at idx %d", idx) {
61			break
62		}
63		var elem, inElem reflect.Value
64		for i := 0; i < vin.Len(); i++ {
65			if vin.Kind() == reflect.Slice {
66				elem = vout.Index(i)
67				inElem = vin.Index(i)
68			} else if vin.Kind() == reflect.Map {
69				keys := vin.MapKeys()
70				elem = vout.MapIndex(keys[i])
71				inElem = vout.MapIndex(keys[i])
72			}
73			assertSingleValue(t, inElem, elem, expectPointer, idx)
74		}
75	default:
76		inElem := vin
77		elem := vout
78		assertSingleValue(t, inElem, elem, expectPointer, idx)
79	}
80}
81
82var testCasesStringSlice = [][]string{
83	{"a", "b", "c", "d", "e"},
84	{"a", "b", "", "", "e"},
85}
86
87func TestStringSlice(t *testing.T) {
88	for idx, in := range testCasesStringSlice {
89		if in == nil {
90			continue
91		}
92		out := StringSlice(in)
93		assertValues(t, in, out, true, idx)
94
95		out2 := StringValueSlice(out)
96		assertValues(t, in, out2, false, idx)
97	}
98}
99
100var testCasesStringValueSlice = [][]*string{
101	{String("a"), String("b"), nil, String("c")},
102}
103
104func TestStringValueSlice(t *testing.T) {
105	for idx, in := range testCasesStringValueSlice {
106		if in == nil {
107			continue
108		}
109		out := StringValueSlice(in)
110		assertValues(t, in, out, false, idx)
111
112		out2 := StringSlice(out)
113		assertValues(t, in, out2, true, idx)
114	}
115}
116
117var testCasesStringMap = []map[string]string{
118	{"a": "1", "b": "2", "c": "3"},
119}
120
121func TestStringMap(t *testing.T) {
122	for idx, in := range testCasesStringMap {
123		if in == nil {
124			continue
125		}
126		out := StringMap(in)
127		assertValues(t, in, out, true, idx)
128
129		out2 := StringValueMap(out)
130		assertValues(t, in, out2, false, idx)
131	}
132}
133
134var testCasesBoolSlice = [][]bool{
135	{true, true, false, false},
136}
137
138func TestBoolSlice(t *testing.T) {
139	for idx, in := range testCasesBoolSlice {
140		if in == nil {
141			continue
142		}
143		out := BoolSlice(in)
144		assertValues(t, in, out, true, idx)
145
146		out2 := BoolValueSlice(out)
147		assertValues(t, in, out2, false, idx)
148	}
149}
150
151var testCasesBoolValueSlice = [][]*bool{
152	{Bool(true), Bool(true), Bool(false), Bool(false)},
153}
154
155func TestBoolValueSlice(t *testing.T) {
156	for idx, in := range testCasesBoolValueSlice {
157		if in == nil {
158			continue
159		}
160		out := BoolValueSlice(in)
161		assertValues(t, in, out, false, idx)
162
163		out2 := BoolSlice(out)
164		assertValues(t, in, out2, true, idx)
165	}
166}
167
168var testCasesBoolMap = []map[string]bool{
169	{"a": true, "b": false, "c": true},
170}
171
172func TestBoolMap(t *testing.T) {
173	for idx, in := range testCasesBoolMap {
174		if in == nil {
175			continue
176		}
177		out := BoolMap(in)
178		assertValues(t, in, out, true, idx)
179
180		out2 := BoolValueMap(out)
181		assertValues(t, in, out2, false, idx)
182	}
183}
184
185var testCasesIntSlice = [][]int{
186	{1, 2, 3, 4},
187}
188
189func TestIntSlice(t *testing.T) {
190	for idx, in := range testCasesIntSlice {
191		if in == nil {
192			continue
193		}
194		out := IntSlice(in)
195		assertValues(t, in, out, true, idx)
196
197		out2 := IntValueSlice(out)
198		assertValues(t, in, out2, false, idx)
199	}
200}
201
202var testCasesIntValueSlice = [][]*int{
203	{Int(1), Int(2), Int(3), Int(4)},
204}
205
206func TestIntValueSlice(t *testing.T) {
207	for idx, in := range testCasesIntValueSlice {
208		if in == nil {
209			continue
210		}
211		out := IntValueSlice(in)
212		assertValues(t, in, out, false, idx)
213
214		out2 := IntSlice(out)
215		assertValues(t, in, out2, true, idx)
216	}
217}
218
219var testCasesIntMap = []map[string]int{
220	{"a": 3, "b": 2, "c": 1},
221}
222
223func TestIntMap(t *testing.T) {
224	for idx, in := range testCasesIntMap {
225		if in == nil {
226			continue
227		}
228		out := IntMap(in)
229		assertValues(t, in, out, true, idx)
230
231		out2 := IntValueMap(out)
232		assertValues(t, in, out2, false, idx)
233	}
234}
235
236var testCasesInt64Slice = [][]int64{
237	{1, 2, 3, 4},
238}
239
240func TestInt64Slice(t *testing.T) {
241	for idx, in := range testCasesInt64Slice {
242		if in == nil {
243			continue
244		}
245		out := Int64Slice(in)
246		assertValues(t, in, out, true, idx)
247
248		out2 := Int64ValueSlice(out)
249		assertValues(t, in, out2, false, idx)
250	}
251}
252
253var testCasesInt64ValueSlice = [][]*int64{
254	{Int64(1), Int64(2), Int64(3), Int64(4)},
255}
256
257func TestInt64ValueSlice(t *testing.T) {
258	for idx, in := range testCasesInt64ValueSlice {
259		if in == nil {
260			continue
261		}
262		out := Int64ValueSlice(in)
263		assertValues(t, in, out, false, idx)
264
265		out2 := Int64Slice(out)
266		assertValues(t, in, out2, true, idx)
267	}
268}
269
270var testCasesInt64Map = []map[string]int64{
271	{"a": 3, "b": 2, "c": 1},
272}
273
274func TestInt64Map(t *testing.T) {
275	for idx, in := range testCasesInt64Map {
276		if in == nil {
277			continue
278		}
279		out := Int64Map(in)
280		assertValues(t, in, out, true, idx)
281
282		out2 := Int64ValueMap(out)
283		assertValues(t, in, out2, false, idx)
284	}
285}
286
287var testCasesFloat64Slice = [][]float64{
288	{1, 2, 3, 4},
289}
290
291func TestFloat64Slice(t *testing.T) {
292	for idx, in := range testCasesFloat64Slice {
293		if in == nil {
294			continue
295		}
296		out := Float64Slice(in)
297		assertValues(t, in, out, true, idx)
298
299		out2 := Float64ValueSlice(out)
300		assertValues(t, in, out2, false, idx)
301	}
302}
303
304var testCasesUintSlice = [][]uint{
305	{1, 2, 3, 4},
306}
307
308func TestUintSlice(t *testing.T) {
309	for idx, in := range testCasesUintSlice {
310		if in == nil {
311			continue
312		}
313		out := UintSlice(in)
314		assertValues(t, in, out, true, idx)
315
316		out2 := UintValueSlice(out)
317		assertValues(t, in, out2, false, idx)
318	}
319}
320
321var testCasesUintValueSlice = [][]*uint{}
322
323func TestUintValueSlice(t *testing.T) {
324	for idx, in := range testCasesUintValueSlice {
325		if in == nil {
326			continue
327		}
328		out := UintValueSlice(in)
329		assertValues(t, in, out, true, idx)
330
331		out2 := UintSlice(out)
332		assertValues(t, in, out2, false, idx)
333	}
334}
335
336var testCasesUintMap = []map[string]uint{
337	{"a": 3, "b": 2, "c": 1},
338}
339
340func TestUintMap(t *testing.T) {
341	for idx, in := range testCasesUintMap {
342		if in == nil {
343			continue
344		}
345		out := UintMap(in)
346		assertValues(t, in, out, true, idx)
347
348		out2 := UintValueMap(out)
349		assertValues(t, in, out2, false, idx)
350	}
351}
352
353var testCasesUint64Slice = [][]uint64{
354	{1, 2, 3, 4},
355}
356
357func TestUint64Slice(t *testing.T) {
358	for idx, in := range testCasesUint64Slice {
359		if in == nil {
360			continue
361		}
362		out := Uint64Slice(in)
363		assertValues(t, in, out, true, idx)
364
365		out2 := Uint64ValueSlice(out)
366		assertValues(t, in, out2, false, idx)
367	}
368}
369
370var testCasesUint64ValueSlice = [][]*uint64{}
371
372func TestUint64ValueSlice(t *testing.T) {
373	for idx, in := range testCasesUint64ValueSlice {
374		if in == nil {
375			continue
376		}
377		out := Uint64ValueSlice(in)
378		assertValues(t, in, out, true, idx)
379
380		out2 := Uint64Slice(out)
381		assertValues(t, in, out2, false, idx)
382	}
383}
384
385var testCasesUint64Map = []map[string]uint64{
386	{"a": 3, "b": 2, "c": 1},
387}
388
389func TestUint64Map(t *testing.T) {
390	for idx, in := range testCasesUint64Map {
391		if in == nil {
392			continue
393		}
394		out := Uint64Map(in)
395		assertValues(t, in, out, true, idx)
396
397		out2 := Uint64ValueMap(out)
398		assertValues(t, in, out2, false, idx)
399	}
400}
401
402var testCasesFloat64ValueSlice = [][]*float64{}
403
404func TestFloat64ValueSlice(t *testing.T) {
405	for idx, in := range testCasesFloat64ValueSlice {
406		if in == nil {
407			continue
408		}
409		out := Float64ValueSlice(in)
410		assertValues(t, in, out, true, idx)
411
412		out2 := Float64Slice(out)
413		assertValues(t, in, out2, false, idx)
414	}
415}
416
417var testCasesFloat64Map = []map[string]float64{
418	{"a": 3, "b": 2, "c": 1},
419}
420
421func TestFloat64Map(t *testing.T) {
422	for idx, in := range testCasesFloat64Map {
423		if in == nil {
424			continue
425		}
426		out := Float64Map(in)
427		assertValues(t, in, out, true, idx)
428
429		out2 := Float64ValueMap(out)
430		assertValues(t, in, out2, false, idx)
431	}
432}
433
434var testCasesTimeSlice = [][]time.Time{
435	{time.Now(), time.Now().AddDate(100, 0, 0)},
436}
437
438func TestTimeSlice(t *testing.T) {
439	for idx, in := range testCasesTimeSlice {
440		if in == nil {
441			continue
442		}
443		out := TimeSlice(in)
444		assertValues(t, in, out, true, idx)
445
446		out2 := TimeValueSlice(out)
447		assertValues(t, in, out2, false, idx)
448	}
449}
450
451var testCasesTimeValueSlice = [][]*time.Time{
452	{Time(time.Now()), Time(time.Now().AddDate(100, 0, 0))},
453}
454
455func TestTimeValueSlice(t *testing.T) {
456	for idx, in := range testCasesTimeValueSlice {
457		if in == nil {
458			continue
459		}
460		out := TimeValueSlice(in)
461		assertValues(t, in, out, false, idx)
462
463		out2 := TimeSlice(out)
464		assertValues(t, in, out2, true, idx)
465	}
466}
467
468var testCasesTimeMap = []map[string]time.Time{
469	{"a": time.Now().AddDate(-100, 0, 0), "b": time.Now()},
470}
471
472func TestTimeMap(t *testing.T) {
473	for idx, in := range testCasesTimeMap {
474		if in == nil {
475			continue
476		}
477		out := TimeMap(in)
478		assertValues(t, in, out, true, idx)
479
480		out2 := TimeValueMap(out)
481		assertValues(t, in, out2, false, idx)
482	}
483}
484
485var testCasesInt32Slice = [][]int32{
486	{1, 2, 3, 4},
487}
488
489func TestInt32Slice(t *testing.T) {
490	for idx, in := range testCasesInt32Slice {
491		if in == nil {
492			continue
493		}
494		out := Int32Slice(in)
495		assertValues(t, in, out, true, idx)
496
497		out2 := Int32ValueSlice(out)
498		assertValues(t, in, out2, false, idx)
499	}
500}
501
502var testCasesInt32ValueSlice = [][]*int32{
503	{Int32(1), Int32(2), Int32(3), Int32(4)},
504}
505
506func TestInt32ValueSlice(t *testing.T) {
507	for idx, in := range testCasesInt32ValueSlice {
508		if in == nil {
509			continue
510		}
511		out := Int32ValueSlice(in)
512		assertValues(t, in, out, false, idx)
513
514		out2 := Int32Slice(out)
515		assertValues(t, in, out2, true, idx)
516	}
517}
518
519var testCasesInt32Map = []map[string]int32{
520	{"a": 3, "b": 2, "c": 1},
521}
522
523func TestInt32Map(t *testing.T) {
524	for idx, in := range testCasesInt32Map {
525		if in == nil {
526			continue
527		}
528		out := Int32Map(in)
529		assertValues(t, in, out, true, idx)
530
531		out2 := Int32ValueMap(out)
532		assertValues(t, in, out2, false, idx)
533	}
534}
535
536var testCasesUint32Slice = [][]uint32{
537	{1, 2, 3, 4},
538}
539
540func TestUint32Slice(t *testing.T) {
541	for idx, in := range testCasesUint32Slice {
542		if in == nil {
543			continue
544		}
545		out := Uint32Slice(in)
546		assertValues(t, in, out, true, idx)
547
548		out2 := Uint32ValueSlice(out)
549		assertValues(t, in, out2, false, idx)
550	}
551}
552
553var testCasesUint32ValueSlice = [][]*uint32{
554	{Uint32(1), Uint32(2), Uint32(3), Uint32(4)},
555}
556
557func TestUint32ValueSlice(t *testing.T) {
558	for idx, in := range testCasesUint32ValueSlice {
559		if in == nil {
560			continue
561		}
562		out := Uint32ValueSlice(in)
563		assertValues(t, in, out, false, idx)
564
565		out2 := Uint32Slice(out)
566		assertValues(t, in, out2, true, idx)
567	}
568}
569
570var testCasesUint32Map = []map[string]uint32{
571	{"a": 3, "b": 2, "c": 1},
572}
573
574func TestUint32Map(t *testing.T) {
575	for idx, in := range testCasesUint32Map {
576		if in == nil {
577			continue
578		}
579		out := Uint32Map(in)
580		assertValues(t, in, out, true, idx)
581
582		out2 := Uint32ValueMap(out)
583		assertValues(t, in, out2, false, idx)
584	}
585}
586
587var testCasesString = []string{"a", "b", "c", "d", "e", ""}
588
589func TestStringValue(t *testing.T) {
590	for idx, in := range testCasesString {
591		out := String(in)
592		assertValues(t, in, out, true, idx)
593
594		out2 := StringValue(out)
595		assertValues(t, in, out2, false, idx)
596	}
597	assert.Zerof(t, StringValue(nil), "expected conversion from nil to return zero value")
598}
599
600var testCasesBool = []bool{true, false}
601
602func TestBoolValue(t *testing.T) {
603	for idx, in := range testCasesBool {
604		out := Bool(in)
605		assertValues(t, in, out, true, idx)
606
607		out2 := BoolValue(out)
608		assertValues(t, in, out2, false, idx)
609	}
610	assert.Zerof(t, BoolValue(nil), "expected conversion from nil to return zero value")
611}
612
613var testCasesInt = []int{1, 2, 3, 0}
614
615func TestIntValue(t *testing.T) {
616	for idx, in := range testCasesInt {
617		out := Int(in)
618		assertValues(t, in, out, true, idx)
619
620		out2 := IntValue(out)
621		assertValues(t, in, out2, false, idx)
622	}
623	assert.Zerof(t, IntValue(nil), "expected conversion from nil to return zero value")
624}
625
626var testCasesInt32 = []int32{1, 2, 3, 0}
627
628func TestInt32Value(t *testing.T) {
629	for idx, in := range testCasesInt32 {
630		out := Int32(in)
631		assertValues(t, in, out, true, idx)
632
633		out2 := Int32Value(out)
634		assertValues(t, in, out2, false, idx)
635	}
636	assert.Zerof(t, Int32Value(nil), "expected conversion from nil to return zero value")
637}
638
639var testCasesInt64 = []int64{1, 2, 3, 0}
640
641func TestInt64Value(t *testing.T) {
642	for idx, in := range testCasesInt64 {
643		out := Int64(in)
644		assertValues(t, in, out, true, idx)
645
646		out2 := Int64Value(out)
647		assertValues(t, in, out2, false, idx)
648	}
649	assert.Zerof(t, Int64Value(nil), "expected conversion from nil to return zero value")
650}
651
652var testCasesUint = []uint{1, 2, 3, 0}
653
654func TestUintValue(t *testing.T) {
655	for idx, in := range testCasesUint {
656		out := Uint(in)
657		assertValues(t, in, out, true, idx)
658
659		out2 := UintValue(out)
660		assertValues(t, in, out2, false, idx)
661	}
662	assert.Zerof(t, UintValue(nil), "expected conversion from nil to return zero value")
663}
664
665var testCasesUint32 = []uint32{1, 2, 3, 0}
666
667func TestUint32Value(t *testing.T) {
668	for idx, in := range testCasesUint32 {
669		out := Uint32(in)
670		assertValues(t, in, out, true, idx)
671
672		out2 := Uint32Value(out)
673		assertValues(t, in, out2, false, idx)
674	}
675	assert.Zerof(t, Uint32Value(nil), "expected conversion from nil to return zero value")
676}
677
678var testCasesUint64 = []uint64{1, 2, 3, 0}
679
680func TestUint64Value(t *testing.T) {
681	for idx, in := range testCasesUint64 {
682		out := Uint64(in)
683		assertValues(t, in, out, true, idx)
684
685		out2 := Uint64Value(out)
686		assertValues(t, in, out2, false, idx)
687	}
688	assert.Zerof(t, Uint64Value(nil), "expected conversion from nil to return zero value")
689}
690
691var testCasesFloat64 = []float64{1, 2, 3, 0}
692
693func TestFloat64Value(t *testing.T) {
694	for idx, in := range testCasesFloat64 {
695		out := Float64(in)
696		assertValues(t, in, out, true, idx)
697
698		out2 := Float64Value(out)
699		assertValues(t, in, out2, false, idx)
700	}
701	assert.Zerof(t, Float64Value(nil), "expected conversion from nil to return zero value")
702}
703
704var testCasesTime = []time.Time{
705	time.Now().AddDate(-100, 0, 0), time.Now(),
706}
707
708func TestTimeValue(t *testing.T) {
709	for idx, in := range testCasesTime {
710		out := Time(in)
711		assertValues(t, in, out, true, idx)
712
713		out2 := TimeValue(out)
714		assertValues(t, in, out2, false, idx)
715	}
716	assert.Zerof(t, TimeValue(nil), "expected conversion from nil to return zero value")
717}
718