diff options
Diffstat (limited to 'vendor/github.com/google/go-querystring/query/encode_test.go')
-rw-r--r-- | vendor/github.com/google/go-querystring/query/encode_test.go | 328 |
1 files changed, 328 insertions, 0 deletions
diff --git a/vendor/github.com/google/go-querystring/query/encode_test.go b/vendor/github.com/google/go-querystring/query/encode_test.go new file mode 100644 index 0000000..77bea5a --- /dev/null +++ b/vendor/github.com/google/go-querystring/query/encode_test.go | |||
@@ -0,0 +1,328 @@ | |||
1 | // Copyright 2013 The Go Authors. All rights reserved. | ||
2 | // Use of this source code is governed by a BSD-style | ||
3 | // license that can be found in the LICENSE file. | ||
4 | |||
5 | package query | ||
6 | |||
7 | import ( | ||
8 | "fmt" | ||
9 | "net/url" | ||
10 | "reflect" | ||
11 | "testing" | ||
12 | "time" | ||
13 | ) | ||
14 | |||
15 | type Nested struct { | ||
16 | A SubNested `url:"a"` | ||
17 | B *SubNested `url:"b"` | ||
18 | Ptr *SubNested `url:"ptr,omitempty"` | ||
19 | } | ||
20 | |||
21 | type SubNested struct { | ||
22 | Value string `url:"value"` | ||
23 | } | ||
24 | |||
25 | func TestValues_types(t *testing.T) { | ||
26 | str := "string" | ||
27 | strPtr := &str | ||
28 | timeVal := time.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC) | ||
29 | |||
30 | tests := []struct { | ||
31 | in interface{} | ||
32 | want url.Values | ||
33 | }{ | ||
34 | { | ||
35 | // basic primitives | ||
36 | struct { | ||
37 | A string | ||
38 | B int | ||
39 | C uint | ||
40 | D float32 | ||
41 | E bool | ||
42 | }{}, | ||
43 | url.Values{ | ||
44 | "A": {""}, | ||
45 | "B": {"0"}, | ||
46 | "C": {"0"}, | ||
47 | "D": {"0"}, | ||
48 | "E": {"false"}, | ||
49 | }, | ||
50 | }, | ||
51 | { | ||
52 | // pointers | ||
53 | struct { | ||
54 | A *string | ||
55 | B *int | ||
56 | C **string | ||
57 | D *time.Time | ||
58 | }{ | ||
59 | A: strPtr, | ||
60 | C: &strPtr, | ||
61 | D: &timeVal, | ||
62 | }, | ||
63 | url.Values{ | ||
64 | "A": {str}, | ||
65 | "B": {""}, | ||
66 | "C": {str}, | ||
67 | "D": {"2000-01-01T12:34:56Z"}, | ||
68 | }, | ||
69 | }, | ||
70 | { | ||
71 | // slices and arrays | ||
72 | struct { | ||
73 | A []string | ||
74 | B []string `url:",comma"` | ||
75 | C []string `url:",space"` | ||
76 | D [2]string | ||
77 | E [2]string `url:",comma"` | ||
78 | F [2]string `url:",space"` | ||
79 | G []*string `url:",space"` | ||
80 | H []bool `url:",int,space"` | ||
81 | I []string `url:",brackets"` | ||
82 | J []string `url:",semicolon"` | ||
83 | K []string `url:",numbered"` | ||
84 | }{ | ||
85 | A: []string{"a", "b"}, | ||
86 | B: []string{"a", "b"}, | ||
87 | C: []string{"a", "b"}, | ||
88 | D: [2]string{"a", "b"}, | ||
89 | E: [2]string{"a", "b"}, | ||
90 | F: [2]string{"a", "b"}, | ||
91 | G: []*string{&str, &str}, | ||
92 | H: []bool{true, false}, | ||
93 | I: []string{"a", "b"}, | ||
94 | J: []string{"a", "b"}, | ||
95 | K: []string{"a", "b"}, | ||
96 | }, | ||
97 | url.Values{ | ||
98 | "A": {"a", "b"}, | ||
99 | "B": {"a,b"}, | ||
100 | "C": {"a b"}, | ||
101 | "D": {"a", "b"}, | ||
102 | "E": {"a,b"}, | ||
103 | "F": {"a b"}, | ||
104 | "G": {"string string"}, | ||
105 | "H": {"1 0"}, | ||
106 | "I[]": {"a", "b"}, | ||
107 | "J": {"a;b"}, | ||
108 | "K0": {"a"}, | ||
109 | "K1": {"b"}, | ||
110 | }, | ||
111 | }, | ||
112 | { | ||
113 | // other types | ||
114 | struct { | ||
115 | A time.Time | ||
116 | B time.Time `url:",unix"` | ||
117 | C bool `url:",int"` | ||
118 | D bool `url:",int"` | ||
119 | }{ | ||
120 | A: time.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC), | ||
121 | B: time.Date(2000, 1, 1, 12, 34, 56, 0, time.UTC), | ||
122 | C: true, | ||
123 | D: false, | ||
124 | }, | ||
125 | url.Values{ | ||
126 | "A": {"2000-01-01T12:34:56Z"}, | ||
127 | "B": {"946730096"}, | ||
128 | "C": {"1"}, | ||
129 | "D": {"0"}, | ||
130 | }, | ||
131 | }, | ||
132 | { | ||
133 | struct { | ||
134 | Nest Nested `url:"nest"` | ||
135 | }{ | ||
136 | Nested{ | ||
137 | A: SubNested{ | ||
138 | Value: "that", | ||
139 | }, | ||
140 | }, | ||
141 | }, | ||
142 | url.Values{ | ||
143 | "nest[a][value]": {"that"}, | ||
144 | "nest[b]": {""}, | ||
145 | }, | ||
146 | }, | ||
147 | { | ||
148 | struct { | ||
149 | Nest Nested `url:"nest"` | ||
150 | }{ | ||
151 | Nested{ | ||
152 | Ptr: &SubNested{ | ||
153 | Value: "that", | ||
154 | }, | ||
155 | }, | ||
156 | }, | ||
157 | url.Values{ | ||
158 | "nest[a][value]": {""}, | ||
159 | "nest[b]": {""}, | ||
160 | "nest[ptr][value]": {"that"}, | ||
161 | }, | ||
162 | }, | ||
163 | { | ||
164 | nil, | ||
165 | url.Values{}, | ||
166 | }, | ||
167 | } | ||
168 | |||
169 | for i, tt := range tests { | ||
170 | v, err := Values(tt.in) | ||
171 | if err != nil { | ||
172 | t.Errorf("%d. Values(%q) returned error: %v", i, tt.in, err) | ||
173 | } | ||
174 | |||
175 | if !reflect.DeepEqual(tt.want, v) { | ||
176 | t.Errorf("%d. Values(%q) returned %v, want %v", i, tt.in, v, tt.want) | ||
177 | } | ||
178 | } | ||
179 | } | ||
180 | |||
181 | func TestValues_omitEmpty(t *testing.T) { | ||
182 | str := "" | ||
183 | s := struct { | ||
184 | a string | ||
185 | A string | ||
186 | B string `url:",omitempty"` | ||
187 | C string `url:"-"` | ||
188 | D string `url:"omitempty"` // actually named omitempty, not an option | ||
189 | E *string `url:",omitempty"` | ||
190 | }{E: &str} | ||
191 | |||
192 | v, err := Values(s) | ||
193 | if err != nil { | ||
194 | t.Errorf("Values(%v) returned error: %v", s, err) | ||
195 | } | ||
196 | |||
197 | want := url.Values{ | ||
198 | "A": {""}, | ||
199 | "omitempty": {""}, | ||
200 | "E": {""}, // E is included because the pointer is not empty, even though the string being pointed to is | ||
201 | } | ||
202 | if !reflect.DeepEqual(want, v) { | ||
203 | t.Errorf("Values(%v) returned %v, want %v", s, v, want) | ||
204 | } | ||
205 | } | ||
206 | |||
207 | type A struct { | ||
208 | B | ||
209 | } | ||
210 | |||
211 | type B struct { | ||
212 | C string | ||
213 | } | ||
214 | |||
215 | type D struct { | ||
216 | B | ||
217 | C string | ||
218 | } | ||
219 | |||
220 | type e struct { | ||
221 | B | ||
222 | C string | ||
223 | } | ||
224 | |||
225 | type F struct { | ||
226 | e | ||
227 | } | ||
228 | |||
229 | func TestValues_embeddedStructs(t *testing.T) { | ||
230 | tests := []struct { | ||
231 | in interface{} | ||
232 | want url.Values | ||
233 | }{ | ||
234 | { | ||
235 | A{B{C: "foo"}}, | ||
236 | url.Values{"C": {"foo"}}, | ||
237 | }, | ||
238 | { | ||
239 | D{B: B{C: "bar"}, C: "foo"}, | ||
240 | url.Values{"C": {"foo", "bar"}}, | ||
241 | }, | ||
242 | { | ||
243 | F{e{B: B{C: "bar"}, C: "foo"}}, // With unexported embed | ||
244 | url.Values{"C": {"foo", "bar"}}, | ||
245 | }, | ||
246 | } | ||
247 | |||
248 | for i, tt := range tests { | ||
249 | v, err := Values(tt.in) | ||
250 | if err != nil { | ||
251 | t.Errorf("%d. Values(%q) returned error: %v", i, tt.in, err) | ||
252 | } | ||
253 | |||
254 | if !reflect.DeepEqual(tt.want, v) { | ||
255 | t.Errorf("%d. Values(%q) returned %v, want %v", i, tt.in, v, tt.want) | ||
256 | } | ||
257 | } | ||
258 | } | ||
259 | |||
260 | func TestValues_invalidInput(t *testing.T) { | ||
261 | _, err := Values("") | ||
262 | if err == nil { | ||
263 | t.Errorf("expected Values() to return an error on invalid input") | ||
264 | } | ||
265 | } | ||
266 | |||
267 | type EncodedArgs []string | ||
268 | |||
269 | func (m EncodedArgs) EncodeValues(key string, v *url.Values) error { | ||
270 | for i, arg := range m { | ||
271 | v.Set(fmt.Sprintf("%s.%d", key, i), arg) | ||
272 | } | ||
273 | return nil | ||
274 | } | ||
275 | |||
276 | func TestValues_Marshaler(t *testing.T) { | ||
277 | s := struct { | ||
278 | Args EncodedArgs `url:"arg"` | ||
279 | }{[]string{"a", "b", "c"}} | ||
280 | v, err := Values(s) | ||
281 | if err != nil { | ||
282 | t.Errorf("Values(%q) returned error: %v", s, err) | ||
283 | } | ||
284 | |||
285 | want := url.Values{ | ||
286 | "arg.0": {"a"}, | ||
287 | "arg.1": {"b"}, | ||
288 | "arg.2": {"c"}, | ||
289 | } | ||
290 | if !reflect.DeepEqual(want, v) { | ||
291 | t.Errorf("Values(%q) returned %v, want %v", s, v, want) | ||
292 | } | ||
293 | } | ||
294 | |||
295 | func TestValues_MarshalerWithNilPointer(t *testing.T) { | ||
296 | s := struct { | ||
297 | Args *EncodedArgs `url:"arg"` | ||
298 | }{} | ||
299 | v, err := Values(s) | ||
300 | if err != nil { | ||
301 | t.Errorf("Values(%v) returned error: %v", s, err) | ||
302 | } | ||
303 | |||
304 | want := url.Values{} | ||
305 | if !reflect.DeepEqual(want, v) { | ||
306 | t.Errorf("Values(%v) returned %v, want %v", s, v, want) | ||
307 | } | ||
308 | } | ||
309 | |||
310 | func TestTagParsing(t *testing.T) { | ||
311 | name, opts := parseTag("field,foobar,foo") | ||
312 | if name != "field" { | ||
313 | t.Fatalf("name = %q, want field", name) | ||
314 | } | ||
315 | for _, tt := range []struct { | ||
316 | opt string | ||
317 | want bool | ||
318 | }{ | ||
319 | {"foobar", true}, | ||
320 | {"foo", true}, | ||
321 | {"bar", false}, | ||
322 | {"field", false}, | ||
323 | } { | ||
324 | if opts.Contains(tt.opt) != tt.want { | ||
325 | t.Errorf("Contains(%q) = %v", tt.opt, !tt.want) | ||
326 | } | ||
327 | } | ||
328 | } | ||