183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh#! /usr/bin/env python
283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehfrom test import test_support
483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport unittest
583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehimport urlparse
683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehRFC1808_BASE = "http://a/b/c/d;p?q#f"
883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehRFC2396_BASE = "http://a/b/c/d;p?q"
983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehRFC3986_BASE = 'http://a/b/c/d;p?q'
1083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew HsiehSIMPLE_BASE  = 'http://a/b/c/d'
1183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# A list of test cases.  Each test case is a two-tuple that contains
1383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh# a string with the query and a dictionary with the expected result.
1483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
1583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehparse_qsl_test_cases = [
1683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    ("", []),
1783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    ("&", []),
1883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    ("&&", []),
1983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    ("=", [('', '')]),
2083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    ("=a", [('', 'a')]),
2183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    ("a", [('a', '')]),
2283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    ("a=", [('a', '')]),
2383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    ("a=", [('a', '')]),
2483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    ("&a=b", [('a', 'b')]),
2583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    ("a=a+b&b=b+c", [('a', 'a b'), ('b', 'b c')]),
2683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    ("a=1&a=2", [('a', '1'), ('a', '2')]),
2783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh]
2883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
2983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehclass UrlParseTestCase(unittest.TestCase):
3083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
3183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def checkRoundtrips(self, url, parsed, split):
3283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        result = urlparse.urlparse(url)
3383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result, parsed)
3483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        t = (result.scheme, result.netloc, result.path,
3583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             result.params, result.query, result.fragment)
3683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(t, parsed)
3783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # put it back together and it should be the same
3883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        result2 = urlparse.urlunparse(result)
3983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result2, url)
4083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result2, result.geturl())
4183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
4283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # the result of geturl() is a fixpoint; we can always parse it
4383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # again to get the same result:
4483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        result3 = urlparse.urlparse(result.geturl())
4583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.geturl(), result.geturl())
4683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3,          result)
4783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.scheme,   result.scheme)
4883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.netloc,   result.netloc)
4983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.path,     result.path)
5083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.params,   result.params)
5183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.query,    result.query)
5283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.fragment, result.fragment)
5383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.username, result.username)
5483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.password, result.password)
5583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.hostname, result.hostname)
5683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.port,     result.port)
5783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
5883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # check the roundtrip using urlsplit() as well
5983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        result = urlparse.urlsplit(url)
6083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result, split)
6183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        t = (result.scheme, result.netloc, result.path,
6283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             result.query, result.fragment)
6383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(t, split)
6483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        result2 = urlparse.urlunsplit(result)
6583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result2, url)
6683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result2, result.geturl())
6783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
6883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # check the fixpoint property of re-parsing the result of geturl()
6983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        result3 = urlparse.urlsplit(result.geturl())
7083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.geturl(), result.geturl())
7183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3,          result)
7283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.scheme,   result.scheme)
7383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.netloc,   result.netloc)
7483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.path,     result.path)
7583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.query,    result.query)
7683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.fragment, result.fragment)
7783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.username, result.username)
7883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.password, result.password)
7983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.hostname, result.hostname)
8083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(result3.port,     result.port)
8183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
8283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_qsl(self):
8383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for orig, expect in parse_qsl_test_cases:
8483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            result = urlparse.parse_qsl(orig, keep_blank_values=True)
8583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(result, expect, "Error parsing %r" % orig)
8683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            expect_without_blanks = [v for v in expect if len(v[1])]
8783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            result = urlparse.parse_qsl(orig, keep_blank_values=False)
8883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(result, expect_without_blanks,
8983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                    "Error parsing %r" % orig)
9083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
9183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
9283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_roundtrips(self):
9383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        testcases = [
9483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('file:///tmp/junk.txt',
9583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('file', '', '/tmp/junk.txt', '', '', ''),
9683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('file', '', '/tmp/junk.txt', '', '')),
9783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('imap://mail.python.org/mbox1',
9883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('imap', 'mail.python.org', '/mbox1', '', '', ''),
9983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('imap', 'mail.python.org', '/mbox1', '', '')),
10083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('mms://wms.sys.hinet.net/cts/Drama/09006251100.asf',
10183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('mms', 'wms.sys.hinet.net', '/cts/Drama/09006251100.asf',
10283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh              '', '', ''),
10383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('mms', 'wms.sys.hinet.net', '/cts/Drama/09006251100.asf',
10483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh              '', '')),
10583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('nfs://server/path/to/file.txt',
10683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('nfs', 'server', '/path/to/file.txt',  '', '', ''),
10783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('nfs', 'server', '/path/to/file.txt', '', '')),
10883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('svn+ssh://svn.zope.org/repos/main/ZConfig/trunk/',
10983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('svn+ssh', 'svn.zope.org', '/repos/main/ZConfig/trunk/',
11083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh              '', '', ''),
11183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('svn+ssh', 'svn.zope.org', '/repos/main/ZConfig/trunk/',
11283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh              '', '')),
11383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('git+ssh://git@github.com/user/project.git',
11483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('git+ssh', 'git@github.com','/user/project.git',
11583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '','',''),
11683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('git+ssh', 'git@github.com','/user/project.git',
11783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '', ''))
11883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ]
11983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for url, parsed, split in testcases:
12083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.checkRoundtrips(url, parsed, split)
12183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
12283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_http_roundtrips(self):
12383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # urlparse.urlsplit treats 'http:' as an optimized special case,
12483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # so we test both 'http:' and 'https:' in all the following.
12583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Three cheers for white box knowledge!
12683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        testcases = [
12783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('://www.python.org',
12883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('www.python.org', '', '', '', ''),
12983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('www.python.org', '', '', '')),
13083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('://www.python.org#abc',
13183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('www.python.org', '', '', '', 'abc'),
13283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('www.python.org', '', '', 'abc')),
13383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('://www.python.org?q=abc',
13483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('www.python.org', '', '', 'q=abc', ''),
13583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('www.python.org', '', 'q=abc', '')),
13683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('://www.python.org/#abc',
13783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('www.python.org', '/', '', '', 'abc'),
13883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('www.python.org', '/', '', 'abc')),
13983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('://a/b/c/d;p?q#f',
14083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('a', '/b/c/d', 'p', 'q', 'f'),
14183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             ('a', '/b/c/d;p', 'q', 'f')),
14283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ]
14383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for scheme in ('http', 'https'):
14483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            for url, parsed, split in testcases:
14583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                url = scheme + url
14683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                parsed = (scheme,) + parsed
14783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                split = (scheme,) + split
14883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                self.checkRoundtrips(url, parsed, split)
14983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def checkJoin(self, base, relurl, expected):
15183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(urlparse.urljoin(base, relurl), expected,
15283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                         (base, relurl, expected))
15383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_unparse_parse(self):
15583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for u in ['Python', './Python','x-newscheme://foo.com/stuff','x://y','x:/y','x:/','/',]:
15683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(urlparse.urlunsplit(urlparse.urlsplit(u)), u)
15783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(urlparse.urlunparse(urlparse.urlparse(u)), u)
15883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
15983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_RFC1808(self):
16083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # "normal" cases from RFC 1808:
16183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, 'g:h', 'g:h')
16283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, 'g', 'http://a/b/c/g')
16383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, './g', 'http://a/b/c/g')
16483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, 'g/', 'http://a/b/c/g/')
16583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '/g', 'http://a/g')
16683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '//g', 'http://g')
16783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, 'g?y', 'http://a/b/c/g?y')
16883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, 'g?y/./x', 'http://a/b/c/g?y/./x')
16983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '#s', 'http://a/b/c/d;p?q#s')
17083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, 'g#s', 'http://a/b/c/g#s')
17183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, 'g#s/./x', 'http://a/b/c/g#s/./x')
17283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, 'g?y#s', 'http://a/b/c/g?y#s')
17383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, 'g;x', 'http://a/b/c/g;x')
17483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, 'g;x?y#s', 'http://a/b/c/g;x?y#s')
17583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '.', 'http://a/b/c/')
17683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, './', 'http://a/b/c/')
17783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '..', 'http://a/b/')
17883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '../', 'http://a/b/')
17983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '../g', 'http://a/b/g')
18083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '../..', 'http://a/')
18183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '../../', 'http://a/')
18283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '../../g', 'http://a/g')
18383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
18483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # "abnormal" cases from RFC 1808:
18583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '', 'http://a/b/c/d;p?q#f')
18683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '../../../g', 'http://a/../g')
18783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '../../../../g', 'http://a/../../g')
18883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '/./g', 'http://a/./g')
18983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '/../g', 'http://a/../g')
19083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, 'g.', 'http://a/b/c/g.')
19183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '.g', 'http://a/b/c/.g')
19283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, 'g..', 'http://a/b/c/g..')
19383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, '..g', 'http://a/b/c/..g')
19483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, './../g', 'http://a/b/g')
19583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, './g/.', 'http://a/b/c/g/')
19683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, 'g/./h', 'http://a/b/c/g/h')
19783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC1808_BASE, 'g/../h', 'http://a/b/c/h')
19883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
19983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # RFC 1808 and RFC 1630 disagree on these (according to RFC 1808),
20083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # so we'll not actually run these tests (which expect 1808 behavior).
20183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        #self.checkJoin(RFC1808_BASE, 'http:g', 'http:g')
20283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        #self.checkJoin(RFC1808_BASE, 'http:', 'http:')
20383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
20483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_RFC2368(self):
20583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Issue 11467: path that starts with a number is not parsed correctly
20683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(urlparse.urlparse('mailto:1337@example.org'),
20783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ('mailto', '', '1337@example.org', '', '', ''))
20883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
20983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_RFC2396(self):
21083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # cases from RFC 2396
21183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g:h', 'g:h')
21283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g', 'http://a/b/c/g')
21383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, './g', 'http://a/b/c/g')
21483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g/', 'http://a/b/c/g/')
21583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '/g', 'http://a/g')
21683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '//g', 'http://g')
21783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g?y', 'http://a/b/c/g?y')
21883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '#s', 'http://a/b/c/d;p?q#s')
21983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g#s', 'http://a/b/c/g#s')
22083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g?y#s', 'http://a/b/c/g?y#s')
22183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g;x', 'http://a/b/c/g;x')
22283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g;x?y#s', 'http://a/b/c/g;x?y#s')
22383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '.', 'http://a/b/c/')
22483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, './', 'http://a/b/c/')
22583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '..', 'http://a/b/')
22683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '../', 'http://a/b/')
22783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '../g', 'http://a/b/g')
22883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '../..', 'http://a/')
22983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '../../', 'http://a/')
23083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '../../g', 'http://a/g')
23183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '', RFC2396_BASE)
23283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '../../../g', 'http://a/../g')
23383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '../../../../g', 'http://a/../../g')
23483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '/./g', 'http://a/./g')
23583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '/../g', 'http://a/../g')
23683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g.', 'http://a/b/c/g.')
23783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '.g', 'http://a/b/c/.g')
23883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g..', 'http://a/b/c/g..')
23983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, '..g', 'http://a/b/c/..g')
24083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, './../g', 'http://a/b/g')
24183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, './g/.', 'http://a/b/c/g/')
24283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g/./h', 'http://a/b/c/g/h')
24383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g/../h', 'http://a/b/c/h')
24483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g;x=1/./y', 'http://a/b/c/g;x=1/y')
24583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g;x=1/../y', 'http://a/b/c/y')
24683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g?y/./x', 'http://a/b/c/g?y/./x')
24783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g?y/../x', 'http://a/b/c/g?y/../x')
24883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g#s/./x', 'http://a/b/c/g#s/./x')
24983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, 'g#s/../x', 'http://a/b/c/g#s/../x')
25083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
25183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_RFC3986(self):
25283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test cases from RFC3986
25383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, '?y','http://a/b/c/d;p?y')
25483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC2396_BASE, ';x', 'http://a/b/c/;x')
25583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g:h','g:h')
25683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g','http://a/b/c/g')
25783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, './g','http://a/b/c/g')
25883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g/','http://a/b/c/g/')
25983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, '/g','http://a/g')
26083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, '//g','http://g')
26183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, '?y','http://a/b/c/d;p?y')
26283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g?y','http://a/b/c/g?y')
26383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, '#s','http://a/b/c/d;p?q#s')
26483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g#s','http://a/b/c/g#s')
26583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g?y#s','http://a/b/c/g?y#s')
26683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, ';x','http://a/b/c/;x')
26783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g;x','http://a/b/c/g;x')
26883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g;x?y#s','http://a/b/c/g;x?y#s')
26983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, '','http://a/b/c/d;p?q')
27083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, '.','http://a/b/c/')
27183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, './','http://a/b/c/')
27283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, '..','http://a/b/')
27383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, '../','http://a/b/')
27483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, '../g','http://a/b/g')
27583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, '../..','http://a/')
27683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, '../../','http://a/')
27783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, '../../g','http://a/g')
27883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
27983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        #Abnormal Examples
28083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
28183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # The 'abnormal scenarios' are incompatible with RFC2986 parsing
28283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Tests are here for reference.
28383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
28483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        #self.checkJoin(RFC3986_BASE, '../../../g','http://a/g')
28583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        #self.checkJoin(RFC3986_BASE, '../../../../g','http://a/g')
28683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        #self.checkJoin(RFC3986_BASE, '/./g','http://a/g')
28783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        #self.checkJoin(RFC3986_BASE, '/../g','http://a/g')
28883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
28983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g.','http://a/b/c/g.')
29083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, '.g','http://a/b/c/.g')
29183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g..','http://a/b/c/g..')
29283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, '..g','http://a/b/c/..g')
29383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, './../g','http://a/b/g')
29483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, './g/.','http://a/b/c/g/')
29583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g/./h','http://a/b/c/g/h')
29683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g/../h','http://a/b/c/h')
29783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g;x=1/./y','http://a/b/c/g;x=1/y')
29883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g;x=1/../y','http://a/b/c/y')
29983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g?y/./x','http://a/b/c/g?y/./x')
30083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g?y/../x','http://a/b/c/g?y/../x')
30183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g#s/./x','http://a/b/c/g#s/./x')
30283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'g#s/../x','http://a/b/c/g#s/../x')
30383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        #self.checkJoin(RFC3986_BASE, 'http:g','http:g') # strict parser
30483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(RFC3986_BASE, 'http:g','http://a/b/c/g') # relaxed parser
30583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
30683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test for issue9721
30783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin('http://a/b/c/de', ';x','http://a/b/c/;x')
30883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
30983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_urljoins(self):
31083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, 'g:h','g:h')
31183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, 'http:g','http://a/b/c/g')
31283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, 'http:','http://a/b/c/d')
31383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, 'g','http://a/b/c/g')
31483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, './g','http://a/b/c/g')
31583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, 'g/','http://a/b/c/g/')
31683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, '/g','http://a/g')
31783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, '//g','http://g')
31883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, '?y','http://a/b/c/d?y')
31983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, 'g?y','http://a/b/c/g?y')
32083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, 'g?y/./x','http://a/b/c/g?y/./x')
32183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, '.','http://a/b/c/')
32283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, './','http://a/b/c/')
32383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, '..','http://a/b/')
32483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, '../','http://a/b/')
32583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, '../g','http://a/b/g')
32683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, '../..','http://a/')
32783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, '../../g','http://a/g')
32883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, '../../../g','http://a/../g')
32983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, './../g','http://a/b/g')
33083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, './g/.','http://a/b/c/g/')
33183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, '/./g','http://a/./g')
33283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, 'g/./h','http://a/b/c/g/h')
33383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, 'g/../h','http://a/b/c/h')
33483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, 'http:g','http://a/b/c/g')
33583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, 'http:','http://a/b/c/d')
33683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, 'http:?y','http://a/b/c/d?y')
33783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, 'http:g?y','http://a/b/c/g?y')
33883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin(SIMPLE_BASE, 'http:g?y/./x','http://a/b/c/g?y/./x')
33983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin('http:///', '..','http:///')
34083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin('', 'http://a/b/c/g?y/./x','http://a/b/c/g?y/./x')
34183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin('', 'http://a/./g', 'http://a/./g')
34283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin('svn://pathtorepo/dir1','dir2','svn://pathtorepo/dir2')
34383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.checkJoin('svn+ssh://pathtorepo/dir1','dir2','svn+ssh://pathtorepo/dir2')
34483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
34583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_RFC2732(self):
34683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for url, hostname, port in [
34783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://Test.python.org:5432/foo/', 'test.python.org', 5432),
34883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://12.34.56.78:5432/foo/', '12.34.56.78', 5432),
34983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://[::1]:5432/foo/', '::1', 5432),
35083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://[dead:beef::1]:5432/foo/', 'dead:beef::1', 5432),
35183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://[dead:beef::]:5432/foo/', 'dead:beef::', 5432),
35283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]:5432/foo/',
35383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             'dead:beef:cafe:5417:affe:8fa3:deaf:feed', 5432),
35483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://[::12.34.56.78]:5432/foo/', '::12.34.56.78', 5432),
35583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://[::ffff:12.34.56.78]:5432/foo/',
35683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '::ffff:12.34.56.78', 5432),
35783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://Test.python.org/foo/', 'test.python.org', None),
35883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://12.34.56.78/foo/', '12.34.56.78', None),
35983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://[::1]/foo/', '::1', None),
36083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://[dead:beef::1]/foo/', 'dead:beef::1', None),
36183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://[dead:beef::]/foo/', 'dead:beef::', None),
36283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://[dead:beef:cafe:5417:affe:8FA3:deaf:feed]/foo/',
36383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             'dead:beef:cafe:5417:affe:8fa3:deaf:feed', None),
36483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://[::12.34.56.78]/foo/', '::12.34.56.78', None),
36583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://[::ffff:12.34.56.78]/foo/',
36683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh             '::ffff:12.34.56.78', None),
36783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ]:
36883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            urlparsed = urlparse.urlparse(url)
36983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual((urlparsed.hostname, urlparsed.port) , (hostname, port))
37083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
37183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for invalid_url in [
37283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                'http://::12.34.56.78]/',
37383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                'http://[::1/foo/',
37483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                'ftp://[::1/foo/bad]/bad',
37583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                'http://[::1/foo/bad]/bad',
37683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                'http://[::ffff:12.34.56.78']:
37783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertRaises(ValueError, urlparse.urlparse, invalid_url)
37883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
37983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_urldefrag(self):
38083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        for url, defrag, frag in [
38183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://python.org#frag', 'http://python.org', 'frag'),
38283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://python.org', 'http://python.org', ''),
38383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://python.org/#frag', 'http://python.org/', 'frag'),
38483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://python.org/', 'http://python.org/', ''),
38583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://python.org/?q#frag', 'http://python.org/?q', 'frag'),
38683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://python.org/?q', 'http://python.org/?q', ''),
38783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://python.org/p#frag', 'http://python.org/p', 'frag'),
38883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ('http://python.org/p?q', 'http://python.org/p?q', ''),
38983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            (RFC1808_BASE, 'http://a/b/c/d;p?q', 'f'),
39083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            (RFC2396_BASE, 'http://a/b/c/d;p?q', ''),
39183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            ]:
39283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh            self.assertEqual(urlparse.urldefrag(url), (defrag, frag))
39383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
39483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_urlsplit_attributes(self):
39583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        url = "HTTP://WWW.PYTHON.ORG/doc/#frag"
39683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p = urlparse.urlsplit(url)
39783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.scheme, "http")
39883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.netloc, "WWW.PYTHON.ORG")
39983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.path, "/doc/")
40083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.query, "")
40183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.fragment, "frag")
40283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.username, None)
40383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.password, None)
40483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.hostname, "www.python.org")
40583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.port, None)
40683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # geturl() won't return exactly the original URL in this case
40783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # since the scheme is always case-normalized
40883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        #self.assertEqual(p.geturl(), url)
40983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
41083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        url = "http://User:Pass@www.python.org:080/doc/?query=yes#frag"
41183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p = urlparse.urlsplit(url)
41283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.scheme, "http")
41383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.netloc, "User:Pass@www.python.org:080")
41483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.path, "/doc/")
41583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.query, "query=yes")
41683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.fragment, "frag")
41783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.username, "User")
41883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.password, "Pass")
41983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.hostname, "www.python.org")
42083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.port, 80)
42183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.geturl(), url)
42283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
42383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Addressing issue1698, which suggests Username can contain
42483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # "@" characters.  Though not RFC compliant, many ftp sites allow
42583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # and request email addresses as usernames.
42683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
42783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        url = "http://User@example.com:Pass@www.python.org:080/doc/?query=yes#frag"
42883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p = urlparse.urlsplit(url)
42983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.scheme, "http")
43083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.netloc, "User@example.com:Pass@www.python.org:080")
43183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.path, "/doc/")
43283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.query, "query=yes")
43383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.fragment, "frag")
43483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.username, "User@example.com")
43583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.password, "Pass")
43683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.hostname, "www.python.org")
43783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.port, 80)
43883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.geturl(), url)
43983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
44083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Verify an illegal port of value greater than 65535 is set as None
44183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        url = "http://www.python.org:65536"
44283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p = urlparse.urlsplit(url)
44383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.port, None)
44483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
44583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_issue14072(self):
44683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p1 = urlparse.urlsplit('tel:+31-641044153')
44783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.scheme, 'tel')
44883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.path, '+31-641044153')
44983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
45083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p2 = urlparse.urlsplit('tel:+31641044153')
45183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p2.scheme, 'tel')
45283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p2.path, '+31641044153')
45383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
45483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Assert for urlparse
45583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p1 = urlparse.urlparse('tel:+31-641044153')
45683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.scheme, 'tel')
45783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.path, '+31-641044153')
45883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
45983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p2 = urlparse.urlparse('tel:+31641044153')
46083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p2.scheme, 'tel')
46183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p2.path, '+31641044153')
46283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
46383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
46483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_telurl_params(self):
46583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p1 = urlparse.urlparse('tel:123-4;phone-context=+1-650-516')
46683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.scheme, 'tel')
46783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.path, '123-4')
46883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.params, 'phone-context=+1-650-516')
46983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
47083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p1 = urlparse.urlparse('tel:+1-201-555-0123')
47183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.scheme, 'tel')
47283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.path, '+1-201-555-0123')
47383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.params, '')
47483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
47583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p1 = urlparse.urlparse('tel:7042;phone-context=example.com')
47683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.scheme, 'tel')
47783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.path, '7042')
47883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.params, 'phone-context=example.com')
47983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
48083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p1 = urlparse.urlparse('tel:863-1234;phone-context=+1-914-555')
48183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.scheme, 'tel')
48283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.path, '863-1234')
48383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p1.params, 'phone-context=+1-914-555')
48483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
48583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
48683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_attributes_bad_port(self):
48783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        """Check handling of non-integer ports."""
48883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p = urlparse.urlsplit("http://www.example.net:foo")
48983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.netloc, "www.example.net:foo")
49083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(ValueError, lambda: p.port)
49183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
49283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p = urlparse.urlparse("http://www.example.net:foo")
49383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.netloc, "www.example.net:foo")
49483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertRaises(ValueError, lambda: p.port)
49583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
49683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_attributes_without_netloc(self):
49783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # This example is straight from RFC 3261.  It looks like it
49883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # should allow the username, hostname, and port to be filled
49983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # in, but doesn't.  Since it's a URI and doesn't use the
50083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # scheme://netloc syntax, the netloc and related attributes
50183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # should be left empty.
50283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        uri = "sip:alice@atlanta.com;maddr=239.255.255.1;ttl=15"
50383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p = urlparse.urlsplit(uri)
50483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.netloc, "")
50583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.username, None)
50683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.password, None)
50783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.hostname, None)
50883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.port, None)
50983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.geturl(), uri)
51083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
51183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p = urlparse.urlparse(uri)
51283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.netloc, "")
51383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.username, None)
51483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.password, None)
51583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.hostname, None)
51683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.port, None)
51783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(p.geturl(), uri)
51883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
51983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_caching(self):
52083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test case for bug #1313119
52183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        uri = "http://example.com/doc/"
52283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        unicode_uri = unicode(uri)
52383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
52483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        urlparse.urlparse(unicode_uri)
52583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        p = urlparse.urlparse(uri)
52683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(type(p.scheme), type(uri))
52783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(type(p.hostname), type(uri))
52883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(type(p.path), type(uri))
52983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
53083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_noslash(self):
53183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Issue 1637: http://foo.com?query is legal
53283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(urlparse.urlparse("http://example.com?blahblah=/foo"),
53383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                         ('http', 'example.com', '', '', 'blahblah=/foo', ''))
53483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
53583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_anyscheme(self):
53683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Issue 7904: s3://foo.com/stuff has netloc "foo.com".
53783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(urlparse.urlparse("s3://foo.com/stuff"),
53883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                         ('s3','foo.com','/stuff','','',''))
53983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(urlparse.urlparse("x-newscheme://foo.com/stuff"),
54083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                         ('x-newscheme','foo.com','/stuff','','',''))
54183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(urlparse.urlparse("x-newscheme://foo.com/stuff?query#fragment"),
54283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                         ('x-newscheme','foo.com','/stuff','','query','fragment'))
54383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(urlparse.urlparse("x-newscheme://foo.com/stuff?query"),
54483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                         ('x-newscheme','foo.com','/stuff','','query',''))
54583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
54683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_withoutscheme(self):
54783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Test urlparse without scheme
54883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Issue 754016: urlparse goes wrong with IP:port without scheme
54983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # RFC 1808 specifies that netloc should start with //, urlparse expects
55083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # the same, otherwise it classifies the portion of url as path.
55183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(urlparse.urlparse("path"),
55283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ('','','path','','',''))
55383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(urlparse.urlparse("//www.python.org:80"),
55483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ('','www.python.org:80','','','',''))
55583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(urlparse.urlparse("http://www.python.org:80"),
55683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ('http','www.python.org:80','','','',''))
55783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
55883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    def test_portseparator(self):
55983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        # Issue 754016 makes changes for port separator ':' from scheme separator
56083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(urlparse.urlparse("path:80"),
56183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ('','','path:80','','',''))
56283760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(urlparse.urlparse("http:"),('http','','','','',''))
56383760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(urlparse.urlparse("https:"),('https','','','','',''))
56483760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh        self.assertEqual(urlparse.urlparse("http://www.python.org:80"),
56583760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh                ('http','www.python.org:80','','','',''))
56683760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
56783760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehdef test_main():
56883760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    test_support.run_unittest(UrlParseTestCase)
56983760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh
57083760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsiehif __name__ == "__main__":
57183760d213fb3bec7b4117d266fcfbf6fe2ba14abAndrew Hsieh    test_main()
572