1// Copyright 2019 DeepMap, Inc.
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.
14package runtime
15
16import (
17	"testing"
18	"time"
19
20	"github.com/stretchr/testify/assert"
21
22	"github.com/deepmap/oapi-codegen/pkg/types"
23)
24
25func TestBindStringToObject(t *testing.T) {
26	var i int
27	assert.NoError(t, BindStringToObject("5", &i))
28	assert.Equal(t, 5, i)
29
30	// Let's make sure we error out on things that can't be the correct
31	// type. Since we're using reflect package setters, we'll have similar
32	// unassignable type errors.
33	assert.Error(t, BindStringToObject("5.7", &i))
34	assert.Error(t, BindStringToObject("foo", &i))
35	assert.Error(t, BindStringToObject("1,2,3", &i))
36
37	var i8 int8
38	assert.NoError(t, BindStringToObject("12", &i8))
39	assert.Equal(t, int8(12), i8)
40
41	assert.Error(t, BindStringToObject("5.7", &i8))
42	assert.Error(t, BindStringToObject("foo", &i8))
43	assert.Error(t, BindStringToObject("1,2,3", &i8))
44
45	var i16 int16
46	assert.NoError(t, BindStringToObject("12", &i16))
47	assert.Equal(t, int16(12), i16)
48
49	assert.Error(t, BindStringToObject("5.7", &i16))
50	assert.Error(t, BindStringToObject("foo", &i16))
51	assert.Error(t, BindStringToObject("1,2,3", &i16))
52
53	var i32 int32
54	assert.NoError(t, BindStringToObject("12", &i32))
55	assert.Equal(t, int32(12), i32)
56
57	assert.Error(t, BindStringToObject("5.7", &i32))
58	assert.Error(t, BindStringToObject("foo", &i32))
59	assert.Error(t, BindStringToObject("1,2,3", &i32))
60
61	var i64 int64
62	assert.NoError(t, BindStringToObject("124", &i64))
63	assert.Equal(t, int64(124), i64)
64
65	assert.Error(t, BindStringToObject("5.7", &i64))
66	assert.Error(t, BindStringToObject("foo", &i64))
67	assert.Error(t, BindStringToObject("1,2,3", &i64))
68
69	var u uint
70	assert.NoError(t, BindStringToObject("5", &u))
71	assert.Equal(t, uint(5), u)
72
73	assert.Error(t, BindStringToObject("5.7", &u))
74	assert.Error(t, BindStringToObject("foo", &u))
75	assert.Error(t, BindStringToObject("1,2,3", &u))
76
77	var u8 uint8
78	assert.NoError(t, BindStringToObject("12", &u8))
79	assert.Equal(t, uint8(12), u8)
80
81	assert.Error(t, BindStringToObject("5.7", &u8))
82	assert.Error(t, BindStringToObject("foo", &u8))
83	assert.Error(t, BindStringToObject("1,2,3", &u8))
84
85	var u16 uint16
86	assert.NoError(t, BindStringToObject("12", &u16))
87	assert.Equal(t, uint16(12), u16)
88
89	assert.Error(t, BindStringToObject("5.7", &u16))
90	assert.Error(t, BindStringToObject("foo", &u16))
91	assert.Error(t, BindStringToObject("1,2,3", &u16))
92
93	var u32 uint32
94	assert.NoError(t, BindStringToObject("12", &u32))
95	assert.Equal(t, uint32(12), u32)
96
97	assert.Error(t, BindStringToObject("5.7", &u32))
98	assert.Error(t, BindStringToObject("foo", &u32))
99	assert.Error(t, BindStringToObject("1,2,3", &u32))
100
101	var u64 uint64
102	assert.NoError(t, BindStringToObject("124", &u64))
103	assert.Equal(t, uint64(124), u64)
104
105	assert.Error(t, BindStringToObject("5.7", &u64))
106	assert.Error(t, BindStringToObject("foo", &u64))
107	assert.Error(t, BindStringToObject("1,2,3", &u64))
108
109	var b bool
110	assert.NoError(t, BindStringToObject("True", &b))
111	assert.Equal(t, true, b)
112	assert.NoError(t, BindStringToObject("true", &b))
113	assert.Equal(t, true, b)
114	assert.NoError(t, BindStringToObject("1", &b))
115	assert.Equal(t, true, b)
116
117	var f64 float64
118	assert.NoError(t, BindStringToObject("1.25", &f64))
119	assert.Equal(t, float64(1.25), f64)
120
121	assert.Error(t, BindStringToObject("foo", &f64))
122	assert.Error(t, BindStringToObject("1,2,3", &f64))
123
124	var f32 float32
125	assert.NoError(t, BindStringToObject("3.125", &f32))
126	assert.Equal(t, float32(3.125), f32)
127
128	assert.Error(t, BindStringToObject("foo", &f32))
129	assert.Error(t, BindStringToObject("1,2,3", &f32))
130
131	// This checks whether binding works through a type alias.
132	type SomeType int
133	var st SomeType
134	assert.NoError(t, BindStringToObject("5", &st))
135	assert.Equal(t, SomeType(5), st)
136
137	// Check time binding
138	now := time.Now().UTC()
139	strTime := now.Format(time.RFC3339Nano)
140	var parsedTime time.Time
141	assert.NoError(t, BindStringToObject(strTime, &parsedTime))
142	parsedTime = parsedTime.UTC()
143	assert.EqualValues(t, now, parsedTime)
144
145	now = now.Truncate(time.Second)
146	strTime = now.Format(time.RFC3339)
147	assert.NoError(t, BindStringToObject(strTime, &parsedTime))
148	parsedTime = parsedTime.UTC()
149	assert.EqualValues(t, now, parsedTime)
150
151	// Checks whether time binding works through a type alias.
152	type AliasedTime time.Time
153	var aliasedTime AliasedTime
154	assert.NoError(t, BindStringToObject(strTime, &aliasedTime))
155	assert.EqualValues(t, now, aliasedTime)
156
157	// Checks whether date binding works directly and through an alias.
158	dateString := "2020-11-05"
159	var dstDate types.Date
160	assert.NoError(t, BindStringToObject(dateString, &dstDate))
161	type AliasedDate types.Date
162	var dstAliasedDate AliasedDate
163	assert.NoError(t, BindStringToObject(dateString, &dstAliasedDate))
164
165	// Checks whether a mock binder works and embedded types
166	var mockBinder MockBinder
167	assert.NoError(t, BindStringToObject(dateString, &mockBinder))
168	assert.EqualValues(t, dateString, mockBinder.Time.Format("2006-01-02"))
169	var dstEmbeddedMockBinder EmbeddedMockBinder
170	assert.NoError(t, BindStringToObject(dateString, &dstEmbeddedMockBinder))
171	assert.EqualValues(t, dateString, dstEmbeddedMockBinder.Time.Format("2006-01-02"))
172}
173