Merge from mainline (167278:168000).
[official-gcc/graphite-test-results.git] / libgo / go / http / url_test.go
blob8198e5f3e79456886f96cd45b6b426c0d9502017
1 // Copyright 2009 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.
5 package http
7 import (
8 "fmt"
9 "os"
10 "reflect"
11 "testing"
14 // TODO(rsc):
15 // test URLUnescape
16 // test URLEscape
17 // test ParseURL
19 type URLTest struct {
20 in string
21 out *URL
22 roundtrip string // expected result of reserializing the URL; empty means same as "in".
25 var urltests = []URLTest{
26 // no path
28 "http://www.google.com",
29 &URL{
30 Raw: "http://www.google.com",
31 Scheme: "http",
32 RawAuthority: "www.google.com",
33 Host: "www.google.com",
35 "",
37 // path
39 "http://www.google.com/",
40 &URL{
41 Raw: "http://www.google.com/",
42 Scheme: "http",
43 RawAuthority: "www.google.com",
44 Host: "www.google.com",
45 RawPath: "/",
46 Path: "/",
48 "",
50 // path with hex escaping
52 "http://www.google.com/file%20one%26two",
53 &URL{
54 Raw: "http://www.google.com/file%20one%26two",
55 Scheme: "http",
56 RawAuthority: "www.google.com",
57 Host: "www.google.com",
58 RawPath: "/file%20one%26two",
59 Path: "/file one&two",
61 "http://www.google.com/file%20one&two",
63 // user
65 "ftp://webmaster@www.google.com/",
66 &URL{
67 Raw: "ftp://webmaster@www.google.com/",
68 Scheme: "ftp",
69 RawAuthority: "webmaster@www.google.com",
70 RawUserinfo: "webmaster",
71 Host: "www.google.com",
72 RawPath: "/",
73 Path: "/",
75 "",
77 // escape sequence in username
79 "ftp://john%20doe@www.google.com/",
80 &URL{
81 Raw: "ftp://john%20doe@www.google.com/",
82 Scheme: "ftp",
83 RawAuthority: "john%20doe@www.google.com",
84 RawUserinfo: "john%20doe",
85 Host: "www.google.com",
86 RawPath: "/",
87 Path: "/",
89 "ftp://john%20doe@www.google.com/",
91 // query
93 "http://www.google.com/?q=go+language",
94 &URL{
95 Raw: "http://www.google.com/?q=go+language",
96 Scheme: "http",
97 RawAuthority: "www.google.com",
98 Host: "www.google.com",
99 RawPath: "/?q=go+language",
100 Path: "/",
101 RawQuery: "q=go+language",
105 // query with hex escaping: NOT parsed
107 "http://www.google.com/?q=go%20language",
108 &URL{
109 Raw: "http://www.google.com/?q=go%20language",
110 Scheme: "http",
111 RawAuthority: "www.google.com",
112 Host: "www.google.com",
113 RawPath: "/?q=go%20language",
114 Path: "/",
115 RawQuery: "q=go%20language",
119 // %20 outside query
121 "http://www.google.com/a%20b?q=c+d",
122 &URL{
123 Raw: "http://www.google.com/a%20b?q=c+d",
124 Scheme: "http",
125 RawAuthority: "www.google.com",
126 Host: "www.google.com",
127 RawPath: "/a%20b?q=c+d",
128 Path: "/a b",
129 RawQuery: "q=c+d",
133 // path without leading /, so no query parsing
135 "http:www.google.com/?q=go+language",
136 &URL{
137 Raw: "http:www.google.com/?q=go+language",
138 Scheme: "http",
139 RawPath: "www.google.com/?q=go+language",
140 Path: "www.google.com/?q=go+language",
141 OpaquePath: true,
143 "http:www.google.com/?q=go+language",
145 // path without leading /, so no query parsing
147 "http:%2f%2fwww.google.com/?q=go+language",
148 &URL{
149 Raw: "http:%2f%2fwww.google.com/?q=go+language",
150 Scheme: "http",
151 RawPath: "%2f%2fwww.google.com/?q=go+language",
152 Path: "//www.google.com/?q=go+language",
153 OpaquePath: true,
155 "http:%2f/www.google.com/?q=go+language",
157 // non-authority
159 "mailto:/webmaster@golang.org",
160 &URL{
161 Raw: "mailto:/webmaster@golang.org",
162 Scheme: "mailto",
163 RawPath: "/webmaster@golang.org",
164 Path: "/webmaster@golang.org",
168 // non-authority
170 "mailto:webmaster@golang.org",
171 &URL{
172 Raw: "mailto:webmaster@golang.org",
173 Scheme: "mailto",
174 RawPath: "webmaster@golang.org",
175 Path: "webmaster@golang.org",
176 OpaquePath: true,
180 // unescaped :// in query should not create a scheme
182 "/foo?query=http://bad",
183 &URL{
184 Raw: "/foo?query=http://bad",
185 RawPath: "/foo?query=http://bad",
186 Path: "/foo",
187 RawQuery: "query=http://bad",
191 // leading // without scheme shouldn't create an authority
193 "//foo",
194 &URL{
195 Raw: "//foo",
196 Scheme: "",
197 RawPath: "//foo",
198 Path: "//foo",
203 "http://user:password@google.com",
204 &URL{
205 Raw: "http://user:password@google.com",
206 Scheme: "http",
207 RawAuthority: "user:password@google.com",
208 RawUserinfo: "user:password",
209 Host: "google.com",
211 "http://user:******@google.com",
214 "http://user:longerpass@google.com",
215 &URL{
216 Raw: "http://user:longerpass@google.com",
217 Scheme: "http",
218 RawAuthority: "user:longerpass@google.com",
219 RawUserinfo: "user:longerpass",
220 Host: "google.com",
222 "http://user:******@google.com",
226 var urlnofragtests = []URLTest{
228 "http://www.google.com/?q=go+language#foo",
229 &URL{
230 Raw: "http://www.google.com/?q=go+language#foo",
231 Scheme: "http",
232 RawAuthority: "www.google.com",
233 Host: "www.google.com",
234 RawPath: "/?q=go+language#foo",
235 Path: "/",
236 RawQuery: "q=go+language#foo",
242 var urlfragtests = []URLTest{
244 "http://www.google.com/?q=go+language#foo",
245 &URL{
246 Raw: "http://www.google.com/?q=go+language#foo",
247 Scheme: "http",
248 RawAuthority: "www.google.com",
249 Host: "www.google.com",
250 RawPath: "/?q=go+language#foo",
251 Path: "/",
252 RawQuery: "q=go+language",
253 Fragment: "foo",
258 "http://www.google.com/?q=go+language#foo%26bar",
259 &URL{
260 Raw: "http://www.google.com/?q=go+language#foo%26bar",
261 Scheme: "http",
262 RawAuthority: "www.google.com",
263 Host: "www.google.com",
264 RawPath: "/?q=go+language#foo%26bar",
265 Path: "/",
266 RawQuery: "q=go+language",
267 Fragment: "foo&bar",
269 "http://www.google.com/?q=go+language#foo&bar",
273 // more useful string for debugging than fmt's struct printer
274 func ufmt(u *URL) string {
275 return fmt.Sprintf("%q, %q, %q, %q, %q, %q, %q, %q, %q",
276 u.Raw, u.Scheme, u.RawPath, u.RawAuthority, u.RawUserinfo,
277 u.Host, u.Path, u.RawQuery, u.Fragment)
280 func DoTest(t *testing.T, parse func(string) (*URL, os.Error), name string, tests []URLTest) {
281 for _, tt := range tests {
282 u, err := parse(tt.in)
283 if err != nil {
284 t.Errorf("%s(%q) returned error %s", name, tt.in, err)
285 continue
287 if !reflect.DeepEqual(u, tt.out) {
288 t.Errorf("%s(%q):\n\thave %v\n\twant %v\n",
289 name, tt.in, ufmt(u), ufmt(tt.out))
294 func TestParseURL(t *testing.T) {
295 DoTest(t, ParseURL, "ParseURL", urltests)
296 DoTest(t, ParseURL, "ParseURL", urlnofragtests)
299 func TestParseURLReference(t *testing.T) {
300 DoTest(t, ParseURLReference, "ParseURLReference", urltests)
301 DoTest(t, ParseURLReference, "ParseURLReference", urlfragtests)
304 func DoTestString(t *testing.T, parse func(string) (*URL, os.Error), name string, tests []URLTest) {
305 for _, tt := range tests {
306 u, err := parse(tt.in)
307 if err != nil {
308 t.Errorf("%s(%q) returned error %s", name, tt.in, err)
309 continue
311 s := u.String()
312 expected := tt.in
313 if len(tt.roundtrip) > 0 {
314 expected = tt.roundtrip
316 if s != expected {
317 t.Errorf("%s(%q).String() == %q (expected %q)", name, tt.in, s, expected)
322 func TestURLString(t *testing.T) {
323 DoTestString(t, ParseURL, "ParseURL", urltests)
324 DoTestString(t, ParseURL, "ParseURL", urlnofragtests)
325 DoTestString(t, ParseURLReference, "ParseURLReference", urltests)
326 DoTestString(t, ParseURLReference, "ParseURLReference", urlfragtests)
329 type URLEscapeTest struct {
330 in string
331 out string
332 err os.Error
335 var unescapeTests = []URLEscapeTest{
339 nil,
342 "abc",
343 "abc",
344 nil,
347 "1%41",
348 "1A",
349 nil,
352 "1%41%42%43",
353 "1ABC",
354 nil,
357 "%4a",
358 "J",
359 nil,
362 "%6F",
363 "o",
364 nil,
367 "%", // not enough characters after %
369 URLEscapeError("%"),
372 "%a", // not enough characters after %
374 URLEscapeError("%a"),
377 "%1", // not enough characters after %
379 URLEscapeError("%1"),
382 "123%45%6", // not enough characters after %
384 URLEscapeError("%6"),
387 "%zzzzz", // invalid hex digits
389 URLEscapeError("%zz"),
393 func TestURLUnescape(t *testing.T) {
394 for _, tt := range unescapeTests {
395 actual, err := URLUnescape(tt.in)
396 if actual != tt.out || (err != nil) != (tt.err != nil) {
397 t.Errorf("URLUnescape(%q) = %q, %s; want %q, %s", tt.in, actual, err, tt.out, tt.err)
402 var escapeTests = []URLEscapeTest{
406 nil,
409 "abc",
410 "abc",
411 nil,
414 "one two",
415 "one+two",
416 nil,
419 "10%",
420 "10%25",
421 nil,
424 " ?&=#+%!<>#\"{}|\\^[]`☺\t",
425 "+%3f%26%3d%23%2b%25!%3c%3e%23%22%7b%7d%7c%5c%5e%5b%5d%60%e2%98%ba%09",
426 nil,
430 func TestURLEscape(t *testing.T) {
431 for _, tt := range escapeTests {
432 actual := URLEscape(tt.in)
433 if tt.out != actual {
434 t.Errorf("URLEscape(%q) = %q, want %q", tt.in, actual, tt.out)
437 // for bonus points, verify that escape:unescape is an identity.
438 roundtrip, err := URLUnescape(actual)
439 if roundtrip != tt.in || err != nil {
440 t.Errorf("URLUnescape(%q) = %q, %s; want %q, %s", actual, roundtrip, err, tt.in, "[no error]")
445 type CanonicalPathTest struct {
446 in string
447 out string
450 var canonicalTests = []CanonicalPathTest{
451 {"", ""},
452 {"/", "/"},
453 {".", ""},
454 {"./", ""},
455 {"/a/", "/a/"},
456 {"a/", "a/"},
457 {"a/./", "a/"},
458 {"./a", "a"},
459 {"/a/../b", "/b"},
460 {"a/../b", "b"},
461 {"a/../../b", "../b"},
462 {"a/.", "a/"},
463 {"../.././a", "../../a"},
464 {"/../.././a", "/../../a"},
465 {"a/b/g/../..", "a/"},
466 {"a/b/..", "a/"},
467 {"a/b/.", "a/b/"},
468 {"a/b/../../../..", "../.."},
469 {"a./", "a./"},
470 {"/../a/b/../../../", "/../../"},
471 {"../a/b/../../../", "../../"},
474 func TestCanonicalPath(t *testing.T) {
475 for _, tt := range canonicalTests {
476 actual := CanonicalPath(tt.in)
477 if tt.out != actual {
478 t.Errorf("CanonicalPath(%q) = %q, want %q", tt.in, actual, tt.out)
483 type UserinfoTest struct {
484 User string
485 Password string
486 Raw string
489 var userinfoTests = []UserinfoTest{
490 {"user", "password", "user:password"},
491 {"foo:bar", "~!@#$%^&*()_+{}|[]\\-=`:;'\"<>?,./",
492 "foo%3abar:~!%40%23$%25%5e&*()_+%7b%7d%7c%5b%5d%5c-=%60%3a;'%22%3c%3e?,.%2f"},
495 func TestEscapeUserinfo(t *testing.T) {
496 for _, tt := range userinfoTests {
497 if raw := EscapeUserinfo(tt.User, tt.Password); raw != tt.Raw {
498 t.Errorf("EscapeUserinfo(%q, %q) = %q, want %q", tt.User, tt.Password, raw, tt.Raw)
503 func TestUnescapeUserinfo(t *testing.T) {
504 for _, tt := range userinfoTests {
505 if user, pass, err := UnescapeUserinfo(tt.Raw); user != tt.User || pass != tt.Password || err != nil {
506 t.Errorf("UnescapeUserinfo(%q) = %q, %q, %v, want %q, %q, nil", tt.Raw, user, pass, err, tt.User, tt.Password)