1 package httpbinding
2
3 import (
4 "fmt"
5 "math/big"
6 "net/http"
7 "reflect"
8 "testing"
9 )
10
11 func TestHeaderValue(t *testing.T) {
12 const keyName = "test-key"
13 const expectedKeyName = "test-key"
14
15 cases := map[string]struct {
16 header http.Header
17 args []interface{}
18 append bool
19 expected http.Header
20 }{
21 "set blob": {
22 header: http.Header{expectedKeyName: []string{"foobar"}},
23 args: []interface{}{[]byte("baz")},
24 expected: map[string][]string{
25 expectedKeyName: {"YmF6"},
26 },
27 },
28 "set boolean": {
29 header: http.Header{expectedKeyName: []string{"foobar"}},
30 args: []interface{}{true},
31 expected: map[string][]string{
32 expectedKeyName: {"true"},
33 },
34 },
35 "set string": {
36 header: http.Header{expectedKeyName: []string{"foobar"}},
37 args: []interface{}{"string value"},
38 expected: map[string][]string{
39 expectedKeyName: {"string value"},
40 },
41 },
42 "set byte": {
43 header: http.Header{expectedKeyName: []string{"127"}},
44 args: []interface{}{int8(127)},
45 expected: map[string][]string{
46 expectedKeyName: {"127"},
47 },
48 },
49 "set short": {
50 header: http.Header{expectedKeyName: []string{"foobar"}},
51 args: []interface{}{int16(32767)},
52 expected: map[string][]string{
53 expectedKeyName: {"32767"},
54 },
55 },
56 "set integer": {
57 header: http.Header{expectedKeyName: []string{"foobar"}},
58 args: []interface{}{int32(2147483647)},
59 expected: map[string][]string{
60 expectedKeyName: {"2147483647"},
61 },
62 },
63 "set long": {
64 header: http.Header{expectedKeyName: []string{"foobar"}},
65 args: []interface{}{int64(9223372036854775807)},
66 expected: map[string][]string{
67 expectedKeyName: {"9223372036854775807"},
68 },
69 },
70 "set float": {
71 header: http.Header{expectedKeyName: []string{"foobar"}},
72 args: []interface{}{float32(3.14159)},
73 expected: map[string][]string{
74 expectedKeyName: {"3.14159"},
75 },
76 },
77 "set double": {
78 header: http.Header{expectedKeyName: []string{"foobar"}},
79 args: []interface{}{float64(3.14159)},
80 expected: map[string][]string{
81 expectedKeyName: {"3.14159"},
82 },
83 },
84 "set bigInteger": {
85 header: http.Header{expectedKeyName: []string{"foobar"}},
86 args: []interface{}{new(big.Int).SetInt64(42)},
87 expected: map[string][]string{
88 expectedKeyName: {"42"},
89 },
90 },
91 "set bigDecimal": {
92 header: http.Header{expectedKeyName: []string{"foobar"}},
93 args: []interface{}{new(big.Float).SetFloat64(1024.10241024)},
94 expected: map[string][]string{
95 expectedKeyName: {"1.02410241024e+03"},
96 },
97 },
98 "add blob": {
99 header: http.Header{expectedKeyName: []string{"foobar"}},
100 args: []interface{}{[]byte("baz")},
101 append: true,
102 expected: map[string][]string{
103 expectedKeyName: {"foobar", "YmF6"},
104 },
105 },
106 "add bool": {
107 header: http.Header{expectedKeyName: []string{"foobar"}},
108 args: []interface{}{true},
109 append: true,
110 expected: map[string][]string{
111 expectedKeyName: {"foobar", "true"},
112 },
113 },
114 "add string": {
115 header: http.Header{expectedKeyName: []string{"foobar"}},
116 args: []interface{}{"string value"},
117 append: true,
118 expected: map[string][]string{
119 expectedKeyName: {"foobar", "string value"},
120 },
121 },
122 "add byte": {
123 header: http.Header{expectedKeyName: []string{"foobar"}},
124 args: []interface{}{int8(127)},
125 append: true,
126 expected: map[string][]string{
127 expectedKeyName: {"foobar", "127"},
128 },
129 },
130 "add short": {
131 header: http.Header{expectedKeyName: []string{"foobar"}},
132 args: []interface{}{int16(32767)},
133 append: true,
134 expected: map[string][]string{
135 expectedKeyName: {"foobar", "32767"},
136 },
137 },
138 "add integer": {
139 header: http.Header{expectedKeyName: []string{"foobar"}},
140 args: []interface{}{int32(2147483647)},
141 append: true,
142 expected: map[string][]string{
143 expectedKeyName: {"foobar", "2147483647"},
144 },
145 },
146 "add long": {
147 header: http.Header{expectedKeyName: []string{"foobar"}},
148 args: []interface{}{int64(9223372036854775807)},
149 append: true,
150 expected: map[string][]string{
151 expectedKeyName: {"foobar", "9223372036854775807"},
152 },
153 },
154 "add float": {
155 header: http.Header{expectedKeyName: []string{"1.61803"}},
156 args: []interface{}{float32(3.14159)},
157 append: true,
158 expected: map[string][]string{
159 expectedKeyName: {"1.61803", "3.14159"},
160 },
161 },
162 "add double": {
163 header: http.Header{expectedKeyName: []string{"foobar"}},
164 args: []interface{}{float64(3.14159)},
165 append: true,
166 expected: map[string][]string{
167 expectedKeyName: {"foobar", "3.14159"},
168 },
169 },
170 "add bigInteger": {
171 header: http.Header{expectedKeyName: []string{"foobar"}},
172 args: []interface{}{new(big.Int).SetInt64(42)},
173 append: true,
174 expected: map[string][]string{
175 expectedKeyName: {"foobar", "42"},
176 },
177 },
178 "add bigDecimal": {
179 header: http.Header{expectedKeyName: []string{"foobar"}},
180 args: []interface{}{new(big.Float).SetFloat64(1024.10241024)},
181 append: true,
182 expected: map[string][]string{
183 expectedKeyName: {"foobar", "1.02410241024e+03"},
184 },
185 },
186 }
187
188 for name, tt := range cases {
189 t.Run(name, func(t *testing.T) {
190 if tt.header == nil {
191 tt.header = http.Header{}
192 }
193
194 hv := newHeaderValue(tt.header, keyName, tt.append)
195
196 if err := setHeader(hv, tt.args); err != nil {
197 t.Fatalf("expected no error, got %v", err)
198 }
199
200 if e, a := tt.expected, hv.header; !reflect.DeepEqual(e, a) {
201 t.Errorf("expected %v, got %v", e, a)
202 }
203 })
204 }
205 }
206
207 func TestHeaders(t *testing.T) {
208 const prefix = "X-Amzn-Meta-"
209 cases := map[string]struct {
210 headers http.Header
211 values map[string]string
212 append bool
213 expected http.Header
214 }{
215 "set": {
216 headers: http.Header{
217 "X-Amzn-Meta-Foo": {"bazValue"},
218 },
219 values: map[string]string{
220 "Foo": "fooValue",
221 " Bar ": "barValue",
222 },
223 expected: http.Header{
224 "X-Amzn-Meta-Foo": {"fooValue"},
225 "X-Amzn-Meta-Bar": {"barValue"},
226 },
227 },
228 "add": {
229 headers: http.Header{
230 "X-Amzn-Meta-Foo": {"bazValue"},
231 },
232 values: map[string]string{
233 "Foo": "fooValue",
234 " Bar ": "barValue",
235 },
236 append: true,
237 expected: http.Header{
238 "X-Amzn-Meta-Foo": {"bazValue", "fooValue"},
239 "X-Amzn-Meta-Bar": {"barValue"},
240 },
241 },
242 }
243
244 for name, tt := range cases {
245 t.Run(name, func(t *testing.T) {
246 headers := Headers{header: tt.headers, prefix: prefix}
247
248 var f func(key string) HeaderValue
249 if tt.append {
250 f = headers.AddHeader
251 } else {
252 f = headers.SetHeader
253 }
254
255 for key, value := range tt.values {
256 f(key).String(value)
257 }
258
259 if e, a := tt.expected, tt.headers; !reflect.DeepEqual(e, a) {
260 t.Errorf("expected %v, but got %v", e, a)
261 }
262 })
263 }
264 }
265
266 func setHeader(hv HeaderValue, args []interface{}) error {
267 value := args[0]
268
269 switch value.(type) {
270 case []byte:
271 return reflectCall(reflect.ValueOf(hv.Blob), args)
272 case bool:
273 return reflectCall(reflect.ValueOf(hv.Boolean), args)
274 case string:
275 return reflectCall(reflect.ValueOf(hv.String), args)
276 case int8:
277 return reflectCall(reflect.ValueOf(hv.Byte), args)
278 case int16:
279 return reflectCall(reflect.ValueOf(hv.Short), args)
280 case int32:
281 return reflectCall(reflect.ValueOf(hv.Integer), args)
282 case int64:
283 return reflectCall(reflect.ValueOf(hv.Long), args)
284 case float32:
285 return reflectCall(reflect.ValueOf(hv.Float), args)
286 case float64:
287 return reflectCall(reflect.ValueOf(hv.Double), args)
288 case *big.Int:
289 return reflectCall(reflect.ValueOf(hv.BigInteger), args)
290 case *big.Float:
291 return reflectCall(reflect.ValueOf(hv.BigDecimal), args)
292 default:
293 return fmt.Errorf("unhandled header value type")
294 }
295 }
296
View as plain text