~bzr-pqm/bzr/bzr.dev

6423.1.1 by Vincent Ladeuil
Cleanup old blackbox tests and then some. Remove os.chdir() calls, caught a few bugs, make sure we don't leave file handles opened.
1
# Copyright (C) 2006-2012 Canonical Ltd
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
16
17
"""Tests for the urlutils wrapper."""
18
19
import os
20
import sys
21
2279.4.2 by Alexander Belchenko
Don't do normpath after abspath, because this function is called inside abspath
22
from bzrlib import osutils, urlutils, win32utils
6240.4.2 by Jelmer Vernooij
Moar tests.
23
from bzrlib.errors import (
24
    InvalidURL,
25
    InvalidURLJoin,
26
    InvalidRebaseURLs,
27
    PathNotChild,
28
    )
1685.1.75 by Wouter van Heyst
more tests handle LANG=C
29
from bzrlib.tests import TestCaseInTempDir, TestCase, TestSkipped
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
30
31
32
class TestUrlToPath(TestCase):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
33
1685.1.49 by John Arbash Meinel
Added bzrlib.urlutils.split and basename + dirname
34
    def test_basename(self):
35
        # bzrlib.urlutils.basename
36
        # Test bzrlib.urlutils.split()
37
        basename = urlutils.basename
38
        if sys.platform == 'win32':
39
            self.assertRaises(InvalidURL, basename, 'file:///path/to/foo')
40
            self.assertEqual('foo', basename('file:///C|/foo'))
1685.1.78 by Wouter van Heyst
more code cleanup
41
            self.assertEqual('foo', basename('file:///C:/foo'))
42
            self.assertEqual('', basename('file:///C:/'))
1685.1.49 by John Arbash Meinel
Added bzrlib.urlutils.split and basename + dirname
43
        else:
44
            self.assertEqual('foo', basename('file:///foo'))
45
            self.assertEqual('', basename('file:///'))
46
47
        self.assertEqual('foo', basename('http://host/path/to/foo'))
48
        self.assertEqual('foo', basename('http://host/path/to/foo/'))
49
        self.assertEqual('',
50
            basename('http://host/path/to/foo/', exclude_trailing_slash=False))
51
        self.assertEqual('path', basename('http://host/path'))
52
        self.assertEqual('', basename('http://host/'))
53
        self.assertEqual('', basename('http://host'))
54
        self.assertEqual('path', basename('http:///nohost/path'))
55
56
        self.assertEqual('path', basename('random+scheme://user:pass@ahost:port/path'))
57
        self.assertEqual('path', basename('random+scheme://user:pass@ahost:port/path/'))
58
        self.assertEqual('', basename('random+scheme://user:pass@ahost:port/'))
59
60
        # relative paths
61
        self.assertEqual('foo', basename('path/to/foo'))
62
        self.assertEqual('foo', basename('path/to/foo/'))
63
        self.assertEqual('', basename('path/to/foo/',
64
            exclude_trailing_slash=False))
65
        self.assertEqual('foo', basename('path/../foo'))
66
        self.assertEqual('foo', basename('../path/foo'))
67
1685.1.51 by John Arbash Meinel
Working on getting normalize_url working.
68
    def test_normalize_url_files(self):
69
        # Test that local paths are properly normalized
70
        normalize_url = urlutils.normalize_url
71
72
        def norm_file(expected, path):
73
            url = normalize_url(path)
74
            self.assertStartsWith(url, 'file:///')
75
            if sys.platform == 'win32':
76
                url = url[len('file:///C:'):]
77
            else:
78
                url = url[len('file://'):]
79
1685.1.53 by John Arbash Meinel
Updated normalize_url
80
            self.assertEndsWith(url, expected)
1685.1.51 by John Arbash Meinel
Working on getting normalize_url working.
81
82
        norm_file('path/to/foo', 'path/to/foo')
83
        norm_file('/path/to/foo', '/path/to/foo')
84
        norm_file('path/to/foo', '../path/to/foo')
85
86
        # Local paths are assumed to *not* be escaped at all
1685.1.75 by Wouter van Heyst
more tests handle LANG=C
87
        try:
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
88
            u'uni/\xb5'.encode(osutils.get_user_encoding())
1685.1.75 by Wouter van Heyst
more tests handle LANG=C
89
        except UnicodeError:
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
90
            # locale cannot handle unicode
1685.1.75 by Wouter van Heyst
more tests handle LANG=C
91
            pass
92
        else:
93
            norm_file('uni/%C2%B5', u'uni/\xb5')
94
1685.1.51 by John Arbash Meinel
Working on getting normalize_url working.
95
        norm_file('uni/%25C2%25B5', u'uni/%C2%B5')
96
        norm_file('uni/%20b', u'uni/ b')
97
        # All the crazy characters get escaped in local paths => file:/// urls
1711.4.4 by John Arbash Meinel
Fix some broken tests because of stupid ntpath.abspath behavior
98
        # The ' ' character must not be at the end, because on win32
99
        # it gets stripped off by ntpath.abspath
5268.7.4 by Jelmer Vernooij
Only skip escaping , and = when actually necessary.
100
        norm_file('%27%20%3B/%3F%3A%40%26%3D%2B%24%2C%23', "' ;/?:@&=+$,#")
1685.1.51 by John Arbash Meinel
Working on getting normalize_url working.
101
102
    def test_normalize_url_hybrid(self):
103
        # Anything with a scheme:// should be treated as a hybrid url
104
        # which changes what characters get escaped.
105
        normalize_url = urlutils.normalize_url
106
107
        eq = self.assertEqual
108
        eq('file:///foo/', normalize_url(u'file:///foo/'))
109
        eq('file:///foo/%20', normalize_url(u'file:///foo/ '))
110
        eq('file:///foo/%20', normalize_url(u'file:///foo/%20'))
111
        # Don't escape reserved characters
112
        eq('file:///ab_c.d-e/%f:?g&h=i+j;k,L#M$',
113
            normalize_url('file:///ab_c.d-e/%f:?g&h=i+j;k,L#M$'))
114
        eq('http://ab_c.d-e/%f:?g&h=i+j;k,L#M$',
115
            normalize_url('http://ab_c.d-e/%f:?g&h=i+j;k,L#M$'))
116
117
        # Escape unicode characters, but not already escaped chars
118
        eq('http://host/ab/%C2%B5/%C2%B5',
119
            normalize_url(u'http://host/ab/%C2%B5/\xb5'))
120
2208.4.1 by Andrew Bennetts
normalize_url should normalise escaping of unreserved characters, like '~'.
121
        # Unescape characters that don't need to be escaped
122
        eq('http://host/~bob%2525-._',
123
                normalize_url('http://host/%7Ebob%2525%2D%2E%5F'))
124
        eq('http://host/~bob%2525-._',
125
                normalize_url(u'http://host/%7Ebob%2525%2D%2E%5F'))
126
1685.1.51 by John Arbash Meinel
Working on getting normalize_url working.
127
        # Normalize verifies URLs when they are not unicode
128
        # (indicating they did not come from the user)
129
        self.assertRaises(InvalidURL, normalize_url, 'http://host/\xb5')
130
        self.assertRaises(InvalidURL, normalize_url, 'http://host/ ')
1685.1.50 by John Arbash Meinel
Added an re for handling scheme paths.
131
132
    def test_url_scheme_re(self):
133
        # Test paths that may be URLs
134
        def test_one(url, scheme_and_path):
135
            """Assert that _url_scheme_re correctly matches
136
137
            :param scheme_and_path: The (scheme, path) that should be matched
138
                can be None, to indicate it should not match
139
            """
140
            m = urlutils._url_scheme_re.match(url)
141
            if scheme_and_path is None:
142
                self.assertEqual(None, m)
143
            else:
144
                self.assertEqual(scheme_and_path[0], m.group('scheme'))
145
                self.assertEqual(scheme_and_path[1], m.group('path'))
146
147
        # Local paths
148
        test_one('/path', None)
149
        test_one('C:/path', None)
150
        test_one('../path/to/foo', None)
151
        test_one(u'../path/to/fo\xe5', None)
152
153
        # Real URLS
154
        test_one('http://host/path/', ('http', 'host/path/'))
155
        test_one('sftp://host/path/to/foo', ('sftp', 'host/path/to/foo'))
156
        test_one('file:///usr/bin', ('file', '/usr/bin'))
157
        test_one('file:///C:/Windows', ('file', '/C:/Windows'))
158
        test_one('file:///C|/Windows', ('file', '/C|/Windows'))
159
        test_one(u'readonly+sftp://host/path/\xe5', ('readonly+sftp', u'host/path/\xe5'))
160
161
        # Weird stuff
162
        # Can't have slashes or colons in the scheme
163
        test_one('/path/to/://foo', None)
5254.1.5 by Gordon Tyler
Fixes according to spiv's review.
164
        test_one('scheme:stuff://foo', ('scheme', 'stuff://foo'))
1685.1.50 by John Arbash Meinel
Added an re for handling scheme paths.
165
        # Must have more than one character for scheme
166
        test_one('C://foo', None)
167
        test_one('ab://foo', ('ab', 'foo'))
168
1685.1.49 by John Arbash Meinel
Added bzrlib.urlutils.split and basename + dirname
169
    def test_dirname(self):
170
        # Test bzrlib.urlutils.dirname()
171
        dirname = urlutils.dirname
172
        if sys.platform == 'win32':
173
            self.assertRaises(InvalidURL, dirname, 'file:///path/to/foo')
174
            self.assertEqual('file:///C|/', dirname('file:///C|/foo'))
175
            self.assertEqual('file:///C|/', dirname('file:///C|/'))
176
        else:
177
            self.assertEqual('file:///', dirname('file:///foo'))
178
            self.assertEqual('file:///', dirname('file:///'))
179
180
        self.assertEqual('http://host/path/to', dirname('http://host/path/to/foo'))
181
        self.assertEqual('http://host/path/to', dirname('http://host/path/to/foo/'))
182
        self.assertEqual('http://host/path/to/foo',
183
            dirname('http://host/path/to/foo/', exclude_trailing_slash=False))
184
        self.assertEqual('http://host/', dirname('http://host/path'))
185
        self.assertEqual('http://host/', dirname('http://host/'))
186
        self.assertEqual('http://host', dirname('http://host'))
187
        self.assertEqual('http:///nohost', dirname('http:///nohost/path'))
188
189
        self.assertEqual('random+scheme://user:pass@ahost:port/',
190
            dirname('random+scheme://user:pass@ahost:port/path'))
191
        self.assertEqual('random+scheme://user:pass@ahost:port/',
192
            dirname('random+scheme://user:pass@ahost:port/path/'))
193
        self.assertEqual('random+scheme://user:pass@ahost:port/',
194
            dirname('random+scheme://user:pass@ahost:port/'))
195
196
        # relative paths
197
        self.assertEqual('path/to', dirname('path/to/foo'))
198
        self.assertEqual('path/to', dirname('path/to/foo/'))
199
        self.assertEqual('path/to/foo',
200
            dirname('path/to/foo/', exclude_trailing_slash=False))
201
        self.assertEqual('path/..', dirname('path/../foo'))
202
        self.assertEqual('../path', dirname('../path/foo'))
5254.2.1 by Gordon Tyler
Fixed how get_transport's convert_path_to_url tests whether a path is actually a URL.
203
    
204
    def test_is_url(self):
205
        self.assertTrue(urlutils.is_url('http://foo/bar'))
206
        self.assertTrue(urlutils.is_url('bzr+ssh://foo/bar'))
207
        self.assertTrue(urlutils.is_url('lp:foo/bar'))
208
        self.assertTrue(urlutils.is_url('file:///foo/bar'))
209
        self.assertFalse(urlutils.is_url(''))
210
        self.assertFalse(urlutils.is_url('foo'))
211
        self.assertFalse(urlutils.is_url('foo/bar'))
212
        self.assertFalse(urlutils.is_url('/foo'))
213
        self.assertFalse(urlutils.is_url('/foo/bar'))
214
        self.assertFalse(urlutils.is_url('C:/'))
215
        self.assertFalse(urlutils.is_url('C:/foo'))
5254.2.5 by Andrew Bennetts
Revert debugging change accidentally committed by Gordon Tyler.
216
        self.assertFalse(urlutils.is_url('C:/foo/bar'))
1685.1.49 by John Arbash Meinel
Added bzrlib.urlutils.split and basename + dirname
217
1685.1.55 by John Arbash Meinel
Adding bzrlib.urlutils.join() to handle joining URLs
218
    def test_join(self):
219
        def test(expected, *args):
220
            joined = urlutils.join(*args)
221
            self.assertEqual(expected, joined)
222
223
        # Test relative path joining
2018.5.100 by Andrew Bennetts
Fix IndexError in urlutils.join with 'http://host/a' and '../../b'.
224
        test('foo', 'foo') # relative fragment with nothing is preserved.
1685.1.55 by John Arbash Meinel
Adding bzrlib.urlutils.join() to handle joining URLs
225
        test('foo/bar', 'foo', 'bar')
226
        test('http://foo/bar', 'http://foo', 'bar')
227
        test('http://foo/bar', 'http://foo', '.', 'bar')
228
        test('http://foo/baz', 'http://foo', 'bar', '../baz')
229
        test('http://foo/bar/baz', 'http://foo', 'bar/baz')
230
        test('http://foo/baz', 'http://foo', 'bar/../baz')
2018.5.93 by Andrew Bennetts
Fix another bug in urlutils.join.
231
        test('http://foo/baz', 'http://foo/bar/', '../baz')
5254.1.1 by Gordon Tyler
Added support to urlutils for URLs such as Launchpad's lp:foobar.
232
        test('lp:foo/bar', 'lp:foo', 'bar')
233
        test('lp:foo/bar/baz', 'lp:foo', 'bar/baz')
1685.1.55 by John Arbash Meinel
Adding bzrlib.urlutils.join() to handle joining URLs
234
235
        # Absolute paths
2018.5.100 by Andrew Bennetts
Fix IndexError in urlutils.join with 'http://host/a' and '../../b'.
236
        test('http://foo', 'http://foo') # abs url with nothing is preserved.
1685.1.55 by John Arbash Meinel
Adding bzrlib.urlutils.join() to handle joining URLs
237
        test('http://bar', 'http://foo', 'http://bar')
238
        test('sftp://bzr/foo', 'http://foo', 'bar', 'sftp://bzr/foo')
239
        test('file:///bar', 'foo', 'file:///bar')
2018.5.92 by Andrew Bennetts
Small bugfix to urlutils.join: join('anything', 'http://bar/a/') should not strip the trailing slash.
240
        test('http://bar/', 'http://foo', 'http://bar/')
241
        test('http://bar/a', 'http://foo', 'http://bar/a')
242
        test('http://bar/a/', 'http://foo', 'http://bar/a/')
5254.1.1 by Gordon Tyler
Added support to urlutils for URLs such as Launchpad's lp:foobar.
243
        test('lp:bar', 'http://foo', 'lp:bar')
244
        test('lp:bar', 'lp:foo', 'lp:bar')
245
        test('file:///stuff', 'lp:foo', 'file:///stuff')
1711.2.49 by John Arbash Meinel
urlutils.join should work for root paths.
246
247
        # From a base path
248
        test('file:///foo', 'file:///', 'foo')
249
        test('file:///bar/foo', 'file:///bar/', 'foo')
250
        test('http://host/foo', 'http://host/', 'foo')
251
        test('http://host/', 'http://host', '')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
252
1685.1.55 by John Arbash Meinel
Adding bzrlib.urlutils.join() to handle joining URLs
253
        # Invalid joinings
254
        # Cannot go above root
2018.5.100 by Andrew Bennetts
Fix IndexError in urlutils.join with 'http://host/a' and '../../b'.
255
        # Implicitly at root:
1685.1.55 by John Arbash Meinel
Adding bzrlib.urlutils.join() to handle joining URLs
256
        self.assertRaises(InvalidURLJoin, urlutils.join,
257
                'http://foo', '../baz')
2018.5.54 by Andrew Bennetts
Fix ChrootTransportDecorator's abspath method to be consistent with its clone
258
        self.assertRaises(InvalidURLJoin, urlutils.join,
259
                'http://foo', '/..')
2018.5.100 by Andrew Bennetts
Fix IndexError in urlutils.join with 'http://host/a' and '../../b'.
260
        # Joining from a path explicitly under the root.
261
        self.assertRaises(InvalidURLJoin, urlutils.join,
262
                'http://foo/a', '../../b')
2379.1.1 by Robert Collins
urlutils improvements from hpss.
263
2018.5.46 by Andrew Bennetts
Fix ChrootTransportDecorator's clone to pass less surprising offsets to the decorated transport's clone.
264
    def test_joinpath(self):
265
        def test(expected, *args):
266
            joined = urlutils.joinpath(*args)
267
            self.assertEqual(expected, joined)
268
269
        # Test a single element
270
        test('foo', 'foo')
271
272
        # Test relative path joining
273
        test('foo/bar', 'foo', 'bar')
274
        test('foo/bar', 'foo', '.', 'bar')
275
        test('foo/baz', 'foo', 'bar', '../baz')
276
        test('foo/bar/baz', 'foo', 'bar/baz')
277
        test('foo/baz', 'foo', 'bar/../baz')
278
279
        # Test joining to an absolute path
280
        test('/foo', '/foo')
281
        test('/foo', '/foo', '.')
282
        test('/foo/bar', '/foo', 'bar')
283
        test('/', '/foo', '..')
284
285
        # Test joining with an absolute path
286
        test('/bar', 'foo', '/bar')
2018.5.53 by Andrew Bennetts
Small fix to urlutils.joinpath that was causing a misbehaviour in
287
288
        # Test joining to a path with a trailing slash
289
        test('foo/bar', 'foo/', 'bar')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
290
2018.5.46 by Andrew Bennetts
Fix ChrootTransportDecorator's clone to pass less surprising offsets to the decorated transport's clone.
291
        # Invalid joinings
292
        # Cannot go above root
293
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '../baz')
2018.5.54 by Andrew Bennetts
Fix ChrootTransportDecorator's abspath method to be consistent with its clone
294
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '..')
295
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '/..')
2018.5.46 by Andrew Bennetts
Fix ChrootTransportDecorator's clone to pass less surprising offsets to the decorated transport's clone.
296
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
297
    def test_join_segment_parameters_raw(self):
298
        join_segment_parameters_raw = urlutils.join_segment_parameters_raw
5163.2.2 by Jelmer Vernooij
Add bzrlib.urlutils.join_subsegments.
299
        self.assertEquals("/somedir/path", 
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
300
            join_segment_parameters_raw("/somedir/path"))
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
301
        self.assertEquals("/somedir/path,rawdata", 
302
            join_segment_parameters_raw("/somedir/path", "rawdata"))
5163.2.2 by Jelmer Vernooij
Add bzrlib.urlutils.join_subsegments.
303
        self.assertRaises(InvalidURLJoin,
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
304
            join_segment_parameters_raw, "/somedir/path",
305
                "rawdata1,rawdata2,rawdata3")
5163.2.2 by Jelmer Vernooij
Add bzrlib.urlutils.join_subsegments.
306
        self.assertEquals("/somedir/path,bla,bar",
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
307
            join_segment_parameters_raw("/somedir/path", "bla", "bar"))
308
        self.assertEquals("/somedir,exist=some/path,bla,bar",
309
            join_segment_parameters_raw("/somedir,exist=some/path",
310
                "bla", "bar"))
5163.2.7 by Jelmer Vernooij
Add type checking.
311
        self.assertRaises(TypeError, join_segment_parameters_raw, 
312
            "/somepath", 42)
5163.2.2 by Jelmer Vernooij
Add bzrlib.urlutils.join_subsegments.
313
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
314
    def test_join_segment_parameters(self):
315
        join_segment_parameters = urlutils.join_segment_parameters
316
        self.assertEquals("/somedir/path", 
317
            join_segment_parameters("/somedir/path", {}))
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
318
        self.assertEquals("/somedir/path,key1=val1", 
319
            join_segment_parameters("/somedir/path", {"key1": "val1"}))
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
320
        self.assertRaises(InvalidURLJoin,
321
            join_segment_parameters, "/somedir/path",
322
            {"branch": "brr,brr,brr"})
323
        self.assertRaises(InvalidURLJoin,
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
324
            join_segment_parameters, "/somedir/path", {"key1=val1": "val2"})
325
        self.assertEquals("/somedir/path,key1=val1,key2=val2",
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
326
            join_segment_parameters("/somedir/path", {
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
327
                "key1": "val1", "key2": "val2"}))
328
        self.assertEquals("/somedir/path,key1=val1,key2=val2",
329
            join_segment_parameters("/somedir/path,key1=val1", {
330
                "key2": "val2"}))
331
        self.assertEquals("/somedir/path,key1=val2",
332
            join_segment_parameters("/somedir/path,key1=val1", {
333
                "key1": "val2"}))
334
        self.assertEquals("/somedir,exist=some/path,key1=val1",
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
335
            join_segment_parameters("/somedir,exist=some/path",
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
336
                {"key1": "val1"}))
337
        self.assertEquals("/,key1=val1,key2=val2",
338
            join_segment_parameters("/,key1=val1", {"key2": "val2"}))
5163.2.7 by Jelmer Vernooij
Add type checking.
339
        self.assertRaises(TypeError,
340
            join_segment_parameters, "/,key1=val1", {"foo": 42})
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
341
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
342
    def test_function_type(self):
343
        if sys.platform == 'win32':
5268.7.21 by Jelmer Vernooij
Cope with segment parameters in urls.
344
            self.assertEqual(urlutils._win32_local_path_to_url,
345
                urlutils.local_path_to_url)
346
            self.assertEqual(urlutils._win32_local_path_from_url,
347
                urlutils.local_path_from_url)
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
348
        else:
5268.7.21 by Jelmer Vernooij
Cope with segment parameters in urls.
349
            self.assertEqual(urlutils._posix_local_path_to_url,
350
                urlutils.local_path_to_url)
351
            self.assertEqual(urlutils._posix_local_path_from_url,
352
                urlutils.local_path_from_url)
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
353
354
    def test_posix_local_path_to_url(self):
355
        to_url = urlutils._posix_local_path_to_url
356
        self.assertEqual('file:///path/to/foo',
357
            to_url('/path/to/foo'))
1685.1.75 by Wouter van Heyst
more tests handle LANG=C
358
5268.7.4 by Jelmer Vernooij
Only skip escaping , and = when actually necessary.
359
        self.assertEqual('file:///path/to/foo%2Cbar',
360
            to_url('/path/to/foo,bar'))
361
1685.1.75 by Wouter van Heyst
more tests handle LANG=C
362
        try:
363
            result = to_url(u'/path/to/r\xe4ksm\xf6rg\xe5s')
364
        except UnicodeError:
365
            raise TestSkipped("local encoding cannot handle unicode")
366
367
        self.assertEqual('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
3234.3.1 by Alexander Belchenko
ensure that local_path_to_url() always returns plain string, not unicode.
368
        self.assertFalse(isinstance(result, unicode))
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
369
370
    def test_posix_local_path_from_url(self):
371
        from_url = urlutils._posix_local_path_from_url
372
        self.assertEqual('/path/to/foo',
373
            from_url('file:///path/to/foo'))
5268.7.21 by Jelmer Vernooij
Cope with segment parameters in urls.
374
        self.assertEqual('/path/to/foo',
375
            from_url('file:///path/to/foo,branch=foo'))
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
376
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
377
            from_url('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
378
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
379
            from_url('file:///path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
4828.1.1 by Michael Hudson
test and fix
380
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
381
            from_url('file://localhost/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
382
383
        self.assertRaises(InvalidURL, from_url, '/path/to/foo')
4828.1.1 by Michael Hudson
test and fix
384
        self.assertRaises(
385
            InvalidURL, from_url,
386
            'file://remotehost/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
387
388
    def test_win32_local_path_to_url(self):
389
        to_url = urlutils._win32_local_path_to_url
1711.4.28 by John Arbash Meinel
Update the test suite for Alexander's patch.
390
        self.assertEqual('file:///C:/path/to/foo',
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
391
            to_url('C:/path/to/foo'))
1711.4.4 by John Arbash Meinel
Fix some broken tests because of stupid ntpath.abspath behavior
392
        # BOGUS: on win32, ntpath.abspath will strip trailing
393
        #       whitespace, so this will always fail
394
        #       Though under linux, it fakes abspath support
395
        #       and thus will succeed
396
        # self.assertEqual('file:///C:/path/to/foo%20',
397
        #     to_url('C:/path/to/foo '))
1711.4.28 by John Arbash Meinel
Update the test suite for Alexander's patch.
398
        self.assertEqual('file:///C:/path/to/f%20oo',
1711.4.4 by John Arbash Meinel
Fix some broken tests because of stupid ntpath.abspath behavior
399
            to_url('C:/path/to/f oo'))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
400
3503.1.2 by adwi2
Permits Windows to serve all paths on all drives.
401
        self.assertEqual('file:///', to_url('/'))
1685.1.75 by Wouter van Heyst
more tests handle LANG=C
402
5268.7.4 by Jelmer Vernooij
Only skip escaping , and = when actually necessary.
403
        self.assertEqual('file:///C:/path/to/foo%2Cbar',
404
            to_url('C:/path/to/foo,bar'))
1685.1.75 by Wouter van Heyst
more tests handle LANG=C
405
        try:
406
            result = to_url(u'd:/path/to/r\xe4ksm\xf6rg\xe5s')
407
        except UnicodeError:
408
            raise TestSkipped("local encoding cannot handle unicode")
409
1711.4.28 by John Arbash Meinel
Update the test suite for Alexander's patch.
410
        self.assertEqual('file:///D:/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
3234.3.1 by Alexander Belchenko
ensure that local_path_to_url() always returns plain string, not unicode.
411
        self.assertFalse(isinstance(result, unicode))
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
412
2162.2.1 by Alexander Belchenko
Testing UNC path conversion
413
    def test_win32_unc_path_to_url(self):
414
        to_url = urlutils._win32_local_path_to_url
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
415
        self.assertEqual('file://HOST/path',
2162.2.1 by Alexander Belchenko
Testing UNC path conversion
416
            to_url(r'\\HOST\path'))
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
417
        self.assertEqual('file://HOST/path',
2162.2.1 by Alexander Belchenko
Testing UNC path conversion
418
            to_url('//HOST/path'))
419
2162.2.5 by Alexander Belchenko
Expand test_win32_unc_path_to_url to check unicode
420
        try:
421
            result = to_url(u'//HOST/path/to/r\xe4ksm\xf6rg\xe5s')
422
        except UnicodeError:
423
            raise TestSkipped("local encoding cannot handle unicode")
424
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
425
        self.assertEqual('file://HOST/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
3234.3.1 by Alexander Belchenko
ensure that local_path_to_url() always returns plain string, not unicode.
426
        self.assertFalse(isinstance(result, unicode))
2162.2.5 by Alexander Belchenko
Expand test_win32_unc_path_to_url to check unicode
427
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
428
    def test_win32_local_path_from_url(self):
429
        from_url = urlutils._win32_local_path_from_url
1711.4.28 by John Arbash Meinel
Update the test suite for Alexander's patch.
430
        self.assertEqual('C:/path/to/foo',
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
431
            from_url('file:///C|/path/to/foo'))
1711.4.28 by John Arbash Meinel
Update the test suite for Alexander's patch.
432
        self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
433
            from_url('file:///d|/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
1711.4.28 by John Arbash Meinel
Update the test suite for Alexander's patch.
434
        self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
1685.1.79 by Wouter van Heyst
cleanup urlutils
435
            from_url('file:///d:/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
3503.1.2 by adwi2
Permits Windows to serve all paths on all drives.
436
        self.assertEqual('/', from_url('file:///'))
5268.7.21 by Jelmer Vernooij
Cope with segment parameters in urls.
437
        self.assertEqual('C:/path/to/foo',
438
            from_url('file:///C|/path/to/foo,branch=foo'))
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
439
5510.2.3 by Jared Bunting
Changed _win32_local_path_from_url to not allow "file:///C:" form.
440
        self.assertRaises(InvalidURL, from_url, 'file:///C:')
5510.2.1 by Jared Bunting
Modified _win32_local_path_from_url to:
441
        self.assertRaises(InvalidURL, from_url, 'file:///c')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
442
        self.assertRaises(InvalidURL, from_url, '/path/to/foo')
443
        # Not a valid _win32 url, no drive letter
444
        self.assertRaises(InvalidURL, from_url, 'file:///path/to/foo')
445
2162.2.1 by Alexander Belchenko
Testing UNC path conversion
446
    def test_win32_unc_path_from_url(self):
447
        from_url = urlutils._win32_local_path_from_url
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
448
        self.assertEqual('//HOST/path', from_url('file://HOST/path'))
5268.7.21 by Jelmer Vernooij
Cope with segment parameters in urls.
449
        self.assertEqual('//HOST/path',
450
            from_url('file://HOST/path,branch=foo'))
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
451
        # despite IE allows 2, 4, 5 and 6 slashes in URL to another machine
452
        # we want to use only 2 slashes
453
        # Firefox understand only 5 slashes in URL, but it's ugly
2162.2.1 by Alexander Belchenko
Testing UNC path conversion
454
        self.assertRaises(InvalidURL, from_url, 'file:////HOST/path')
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
455
        self.assertRaises(InvalidURL, from_url, 'file://///HOST/path')
2162.2.1 by Alexander Belchenko
Testing UNC path conversion
456
        self.assertRaises(InvalidURL, from_url, 'file://////HOST/path')
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
457
        # check for file://C:/ instead of file:///C:/
458
        self.assertRaises(InvalidURL, from_url, 'file://C:/path')
2162.2.1 by Alexander Belchenko
Testing UNC path conversion
459
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
460
    def test_win32_extract_drive_letter(self):
1711.2.43 by John Arbash Meinel
Split out win32 specific code so that it can be tested on all platforms.
461
        extract = urlutils._win32_extract_drive_letter
462
        self.assertEqual(('file:///C:', '/foo'), extract('file://', '/C:/foo'))
463
        self.assertEqual(('file:///d|', '/path'), extract('file://', '/d|/path'))
464
        self.assertRaises(InvalidURL, extract, 'file://', '/path')
6123.3.1 by Martin
More comprehensive testing for urlutils._win32_extract_drive_letter
465
        # Root drives without slash treated as invalid, see bug #841322
466
        self.assertEqual(('file:///C:', '/'), extract('file://', '/C:/'))
467
        self.assertRaises(InvalidURL, extract, 'file://', '/C:')
468
        # Invalid without drive separator or following forward slash
469
        self.assertRaises(InvalidURL, extract, 'file://', '/C')
470
        self.assertRaises(InvalidURL, extract, 'file://', '/C:ool')
1711.2.43 by John Arbash Meinel
Split out win32 specific code so that it can be tested on all platforms.
471
1685.1.49 by John Arbash Meinel
Added bzrlib.urlutils.split and basename + dirname
472
    def test_split(self):
473
        # Test bzrlib.urlutils.split()
474
        split = urlutils.split
475
        if sys.platform == 'win32':
476
            self.assertRaises(InvalidURL, split, 'file:///path/to/foo')
477
            self.assertEqual(('file:///C|/', 'foo'), split('file:///C|/foo'))
1685.1.79 by Wouter van Heyst
cleanup urlutils
478
            self.assertEqual(('file:///C:/', ''), split('file:///C:/'))
1685.1.49 by John Arbash Meinel
Added bzrlib.urlutils.split and basename + dirname
479
        else:
480
            self.assertEqual(('file:///', 'foo'), split('file:///foo'))
481
            self.assertEqual(('file:///', ''), split('file:///'))
482
483
        self.assertEqual(('http://host/path/to', 'foo'), split('http://host/path/to/foo'))
484
        self.assertEqual(('http://host/path/to', 'foo'), split('http://host/path/to/foo/'))
485
        self.assertEqual(('http://host/path/to/foo', ''),
486
            split('http://host/path/to/foo/', exclude_trailing_slash=False))
487
        self.assertEqual(('http://host/', 'path'), split('http://host/path'))
488
        self.assertEqual(('http://host/', ''), split('http://host/'))
489
        self.assertEqual(('http://host', ''), split('http://host'))
490
        self.assertEqual(('http:///nohost', 'path'), split('http:///nohost/path'))
491
492
        self.assertEqual(('random+scheme://user:pass@ahost:port/', 'path'),
493
            split('random+scheme://user:pass@ahost:port/path'))
494
        self.assertEqual(('random+scheme://user:pass@ahost:port/', 'path'),
495
            split('random+scheme://user:pass@ahost:port/path/'))
496
        self.assertEqual(('random+scheme://user:pass@ahost:port/', ''),
497
            split('random+scheme://user:pass@ahost:port/'))
498
499
        # relative paths
500
        self.assertEqual(('path/to', 'foo'), split('path/to/foo'))
501
        self.assertEqual(('path/to', 'foo'), split('path/to/foo/'))
502
        self.assertEqual(('path/to/foo', ''),
503
            split('path/to/foo/', exclude_trailing_slash=False))
504
        self.assertEqual(('path/..', 'foo'), split('path/../foo'))
505
        self.assertEqual(('../path', 'foo'), split('../path/foo'))
506
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
507
    def test_split_segment_parameters_raw(self):
508
        split_segment_parameters_raw = urlutils.split_segment_parameters_raw
6278.1.2 by Martin Packman
Comment which checks tests for split_segment_parameters are actually doing currently
509
        # Check relative references with absolute paths
5163.2.1 by Jelmer Vernooij
Add urlutils.split_subsegments.
510
        self.assertEquals(("/some/path", []),
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
511
            split_segment_parameters_raw("/some/path"))
5163.2.1 by Jelmer Vernooij
Add urlutils.split_subsegments.
512
        self.assertEquals(("/some/path", ["tip"]),
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
513
            split_segment_parameters_raw("/some/path,tip"))
5163.2.1 by Jelmer Vernooij
Add urlutils.split_subsegments.
514
        self.assertEquals(("/some,dir/path", ["tip"]),
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
515
            split_segment_parameters_raw("/some,dir/path,tip"))
5163.2.1 by Jelmer Vernooij
Add urlutils.split_subsegments.
516
        self.assertEquals(("/somedir/path", ["heads%2Ftip"]),
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
517
            split_segment_parameters_raw("/somedir/path,heads%2Ftip"))
5163.2.1 by Jelmer Vernooij
Add urlutils.split_subsegments.
518
        self.assertEquals(("/somedir/path", ["heads%2Ftip", "bar"]),
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
519
            split_segment_parameters_raw("/somedir/path,heads%2Ftip,bar"))
6278.1.2 by Martin Packman
Comment which checks tests for split_segment_parameters are actually doing currently
520
        # Check relative references with relative paths
6278.1.1 by Martin Packman
Correct assertions for relative paths in tests for split_segment_parameters
521
        self.assertEquals(("", ["key1=val1"]),
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
522
            split_segment_parameters_raw(",key1=val1"))
523
        self.assertEquals(("foo/", ["key1=val1"]),
524
            split_segment_parameters_raw("foo/,key1=val1"))
6278.1.1 by Martin Packman
Correct assertions for relative paths in tests for split_segment_parameters
525
        self.assertEquals(("foo", ["key1=val1"]),
5268.7.21 by Jelmer Vernooij
Cope with segment parameters in urls.
526
            split_segment_parameters_raw("foo,key1=val1"))
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
527
        self.assertEquals(("foo/base,la=bla/other/elements", []),
528
            split_segment_parameters_raw("foo/base,la=bla/other/elements"))
529
        self.assertEquals(("foo/base,la=bla/other/elements", ["a=b"]),
530
            split_segment_parameters_raw("foo/base,la=bla/other/elements,a=b"))
6278.1.2 by Martin Packman
Comment which checks tests for split_segment_parameters are actually doing currently
531
        # TODO: Check full URLs as well as relative references
5163.2.1 by Jelmer Vernooij
Add urlutils.split_subsegments.
532
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
533
    def test_split_segment_parameters(self):
534
        split_segment_parameters = urlutils.split_segment_parameters
6278.1.2 by Martin Packman
Comment which checks tests for split_segment_parameters are actually doing currently
535
        # Check relative references with absolute paths
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
536
        self.assertEquals(("/some/path", {}),
537
            split_segment_parameters("/some/path"))
538
        self.assertEquals(("/some/path", {"branch": "tip"}),
539
            split_segment_parameters("/some/path,branch=tip"))
540
        self.assertEquals(("/some,dir/path", {"branch": "tip"}),
541
            split_segment_parameters("/some,dir/path,branch=tip"))
542
        self.assertEquals(("/somedir/path", {"ref": "heads%2Ftip"}),
543
            split_segment_parameters("/somedir/path,ref=heads%2Ftip"))
544
        self.assertEquals(("/somedir/path",
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
545
            {"ref": "heads%2Ftip", "key1": "val1"}),
546
            split_segment_parameters(
547
                "/somedir/path,ref=heads%2Ftip,key1=val1"))
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
548
        self.assertEquals(("/somedir/path", {"ref": "heads%2F=tip"}),
549
            split_segment_parameters("/somedir/path,ref=heads%2F=tip"))
6278.1.2 by Martin Packman
Comment which checks tests for split_segment_parameters are actually doing currently
550
        # Check relative references with relative paths
6278.1.1 by Martin Packman
Correct assertions for relative paths in tests for split_segment_parameters
551
        self.assertEquals(("", {"key1": "val1"}),
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
552
            split_segment_parameters(",key1=val1"))
553
        self.assertEquals(("foo/", {"key1": "val1"}),
554
            split_segment_parameters("foo/,key1=val1"))
555
        self.assertEquals(("foo/base,key1=val1/other/elements", {}),
556
            split_segment_parameters("foo/base,key1=val1/other/elements"))
557
        self.assertEquals(("foo/base,key1=val1/other/elements",
558
            {"key2": "val2"}), split_segment_parameters(
559
                "foo/base,key1=val1/other/elements,key2=val2"))
6278.1.2 by Martin Packman
Comment which checks tests for split_segment_parameters are actually doing currently
560
        # TODO: Check full URLs as well as relative references
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
561
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
562
    def test_win32_strip_local_trailing_slash(self):
1711.2.44 by John Arbash Meinel
Factor out another win32 special case and add platform independent tests for it.
563
        strip = urlutils._win32_strip_local_trailing_slash
564
        self.assertEqual('file://', strip('file://'))
565
        self.assertEqual('file:///', strip('file:///'))
566
        self.assertEqual('file:///C', strip('file:///C'))
567
        self.assertEqual('file:///C:', strip('file:///C:'))
568
        self.assertEqual('file:///d|', strip('file:///d|'))
569
        self.assertEqual('file:///C:/', strip('file:///C:/'))
570
        self.assertEqual('file:///C:/a', strip('file:///C:/a/'))
571
1685.1.48 by John Arbash Meinel
Updated strip_trailing_slash to support lots more url stuff, added tests
572
    def test_strip_trailing_slash(self):
573
        sts = urlutils.strip_trailing_slash
574
        if sys.platform == 'win32':
575
            self.assertEqual('file:///C|/', sts('file:///C|/'))
1685.1.79 by Wouter van Heyst
cleanup urlutils
576
            self.assertEqual('file:///C:/foo', sts('file:///C:/foo'))
1685.1.48 by John Arbash Meinel
Updated strip_trailing_slash to support lots more url stuff, added tests
577
            self.assertEqual('file:///C|/foo', sts('file:///C|/foo/'))
578
        else:
579
            self.assertEqual('file:///', sts('file:///'))
580
            self.assertEqual('file:///foo', sts('file:///foo'))
581
            self.assertEqual('file:///foo', sts('file:///foo/'))
582
583
        self.assertEqual('http://host/', sts('http://host/'))
584
        self.assertEqual('http://host/foo', sts('http://host/foo'))
585
        self.assertEqual('http://host/foo', sts('http://host/foo/'))
586
587
        # No need to fail just because the slash is missing
588
        self.assertEqual('http://host', sts('http://host'))
589
        # TODO: jam 20060502 Should this raise InvalidURL?
590
        self.assertEqual('file://', sts('file://'))
591
592
        self.assertEqual('random+scheme://user:pass@ahost:port/path',
593
            sts('random+scheme://user:pass@ahost:port/path'))
594
        self.assertEqual('random+scheme://user:pass@ahost:port/path',
595
            sts('random+scheme://user:pass@ahost:port/path/'))
596
        self.assertEqual('random+scheme://user:pass@ahost:port/',
597
            sts('random+scheme://user:pass@ahost:port/'))
598
599
        # Make sure relative paths work too
600
        self.assertEqual('path/to/foo', sts('path/to/foo'))
601
        self.assertEqual('path/to/foo', sts('path/to/foo/'))
602
        self.assertEqual('../to/foo', sts('../to/foo/'))
603
        self.assertEqual('path/../foo', sts('path/../foo/'))
604
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
605
    def test_unescape_for_display_utf8(self):
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
606
        # Test that URLs are converted to nice unicode strings for display
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
607
        def test(expected, url, encoding='utf-8'):
608
            disp_url = urlutils.unescape_for_display(url, encoding=encoding)
1685.1.58 by Martin Pool
urlutils.unescape_for_display should return Unicode
609
            self.assertIsInstance(disp_url, unicode)
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
610
            self.assertEqual(expected, disp_url)
1685.1.79 by Wouter van Heyst
cleanup urlutils
611
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
612
        test('http://foo', 'http://foo')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
613
        if sys.platform == 'win32':
1711.7.13 by John Arbash Meinel
Fix expected value for urlutils tests
614
            test('C:/foo/path', 'file:///C|/foo/path')
615
            test('C:/foo/path', 'file:///C:/foo/path')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
616
        else:
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
617
            test('/foo/path', 'file:///foo/path')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
618
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
619
        test('http://foo/%2Fbaz', 'http://foo/%2Fbaz')
1685.1.58 by Martin Pool
urlutils.unescape_for_display should return Unicode
620
        test(u'http://host/r\xe4ksm\xf6rg\xe5s',
621
             'http://host/r%C3%A4ksm%C3%B6rg%C3%A5s')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
622
623
        # Make sure special escaped characters stay escaped
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
624
        test(u'http://host/%3B%2F%3F%3A%40%26%3D%2B%24%2C%23',
1685.1.58 by Martin Pool
urlutils.unescape_for_display should return Unicode
625
             'http://host/%3B%2F%3F%3A%40%26%3D%2B%24%2C%23')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
626
627
        # Can we handle sections that don't have utf-8 encoding?
1685.1.58 by Martin Pool
urlutils.unescape_for_display should return Unicode
628
        test(u'http://host/%EE%EE%EE/r\xe4ksm\xf6rg\xe5s',
629
             'http://host/%EE%EE%EE/r%C3%A4ksm%C3%B6rg%C3%A5s')
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
630
631
        # Test encoding into output that can handle some characters
1685.1.58 by Martin Pool
urlutils.unescape_for_display should return Unicode
632
        test(u'http://host/%EE%EE%EE/r\xe4ksm\xf6rg\xe5s',
633
             'http://host/%EE%EE%EE/r%C3%A4ksm%C3%B6rg%C3%A5s',
634
             encoding='iso-8859-1')
635
636
        # This one can be encoded into utf8
637
        test(u'http://host/\u062c\u0648\u062c\u0648',
638
             'http://host/%d8%ac%d9%88%d8%ac%d9%88',
639
             encoding='utf-8')
640
641
        # This can't be put into 8859-1 and so stays as escapes
642
        test(u'http://host/%d8%ac%d9%88%d8%ac%d9%88',
643
             'http://host/%d8%ac%d9%88%d8%ac%d9%88',
644
             encoding='iso-8859-1')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
645
646
    def test_escape(self):
647
        self.assertEqual('%25', urlutils.escape('%'))
648
        self.assertEqual('%C3%A5', urlutils.escape(u'\xe5'))
3234.3.1 by Alexander Belchenko
ensure that local_path_to_url() always returns plain string, not unicode.
649
        self.assertFalse(isinstance(urlutils.escape(u'\xe5'), unicode))
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
650
4098.3.1 by Jonathan Lange
Don't escape tildes
651
    def test_escape_tildes(self):
652
        self.assertEqual('~foo', urlutils.escape('~foo'))
653
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
654
    def test_unescape(self):
655
        self.assertEqual('%', urlutils.unescape('%25'))
656
        self.assertEqual(u'\xe5', urlutils.unescape('%C3%A5'))
657
658
        self.assertRaises(InvalidURL, urlutils.unescape, u'\xe5')
659
        self.assertRaises(InvalidURL, urlutils.unescape, '\xe5')
660
        self.assertRaises(InvalidURL, urlutils.unescape, '%E5')
661
662
    def test_escape_unescape(self):
663
        self.assertEqual(u'\xe5', urlutils.unescape(urlutils.escape(u'\xe5')))
664
        self.assertEqual('%', urlutils.unescape(urlutils.escape('%')))
665
1685.1.70 by Wouter van Heyst
working on get_parent, set_parent and relative urls, broken
666
    def test_relative_url(self):
667
        def test(expected, base, other):
668
            result = urlutils.relative_url(base, other)
669
            self.assertEqual(expected, result)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
670
1685.1.70 by Wouter van Heyst
working on get_parent, set_parent and relative urls, broken
671
        test('a', 'http://host/', 'http://host/a')
1685.1.71 by Wouter van Heyst
change branch.{get,set}_parent to store a relative path but return full urls
672
        test('http://entirely/different', 'sftp://host/branch',
673
                    'http://entirely/different')
674
        test('../person/feature', 'http://host/branch/mainline',
675
                    'http://host/branch/person/feature')
1685.1.70 by Wouter van Heyst
working on get_parent, set_parent and relative urls, broken
676
        test('..', 'http://host/branch', 'http://host/')
677
        test('http://host2/branch', 'http://host1/branch', 'http://host2/branch')
1685.1.71 by Wouter van Heyst
change branch.{get,set}_parent to store a relative path but return full urls
678
        test('.', 'http://host1/branch', 'http://host1/branch')
679
        test('../../../branch/2b', 'file:///home/jelmer/foo/bar/2b',
680
                    'file:///home/jelmer/branch/2b')
681
        test('../../branch/2b', 'sftp://host/home/jelmer/bar/2b',
682
                    'sftp://host/home/jelmer/branch/2b')
1685.1.79 by Wouter van Heyst
cleanup urlutils
683
        test('../../branch/feature/%2b', 'http://host/home/jelmer/bar/%2b',
684
                    'http://host/home/jelmer/branch/feature/%2b')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
685
        test('../../branch/feature/2b', 'http://host/home/jelmer/bar/2b/',
1685.1.71 by Wouter van Heyst
change branch.{get,set}_parent to store a relative path but return full urls
686
                    'http://host/home/jelmer/branch/feature/2b')
687
        # relative_url should preserve a trailing slash
688
        test('../../branch/feature/2b/', 'http://host/home/jelmer/bar/2b/',
689
                    'http://host/home/jelmer/branch/feature/2b/')
690
        test('../../branch/feature/2b/', 'http://host/home/jelmer/bar/2b',
691
                    'http://host/home/jelmer/branch/feature/2b/')
692
693
        # TODO: treat http://host as http://host/
694
        #       relative_url is typically called from a branch.base or
695
        #       transport.base which always ends with a /
696
        #test('a', 'http://host', 'http://host/a')
697
        test('http://host/a', 'http://host', 'http://host/a')
698
        #test('.', 'http://host', 'http://host/')
699
        test('http://host/', 'http://host', 'http://host/')
700
        #test('.', 'http://host/', 'http://host')
701
        test('http://host', 'http://host/', 'http://host')
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
702
3139.2.1 by Alexander Belchenko
bugfix #90847: fix problem with parent location on another logical drive
703
        # On Windows file:///C:/path/to and file:///D:/other/path
704
        # should not use relative url over the non-existent '/' directory.
705
        if sys.platform == 'win32':
706
            # on the same drive
707
            test('../../other/path',
708
                'file:///C:/path/to', 'file:///C:/other/path')
709
            #~next two tests is failed, i.e. urlutils.relative_url expects
710
            #~to see normalized file URLs?
711
            #~test('../../other/path',
712
            #~    'file:///C:/path/to', 'file:///c:/other/path')
713
            #~test('../../other/path',
714
            #~    'file:///C:/path/to', 'file:///C|/other/path')
715
716
            # check UNC paths too
717
            test('../../other/path',
718
                'file://HOST/base/path/to', 'file://HOST/base/other/path')
719
            # on different drives
720
            test('file:///D:/other/path',
721
                'file:///C:/path/to', 'file:///D:/other/path')
722
            # TODO: strictly saying in UNC path //HOST/base is full analog
723
            # of drive letter for hard disk, and this situation is also
724
            # should be exception from rules. [bialix 20071221]
725
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
726
727
class TestCwdToURL(TestCaseInTempDir):
6423.1.1 by Vincent Ladeuil
Cleanup old blackbox tests and then some. Remove os.chdir() calls, caught a few bugs, make sure we don't leave file handles opened.
728
    """Test that local_path_to_url works based on the cwd"""
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
729
730
    def test_dot(self):
731
        # This test will fail if getcwd is not ascii
1830.3.17 by John Arbash Meinel
list_files() with wrong normalized_filename code raises exceptions. Fix this
732
        os.mkdir('mytest')
733
        os.chdir('mytest')
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
734
735
        url = urlutils.local_path_to_url('.')
1830.3.17 by John Arbash Meinel
list_files() with wrong normalized_filename code raises exceptions. Fix this
736
        self.assertEndsWith(url, '/mytest')
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
737
738
    def test_non_ascii(self):
2279.4.2 by Alexander Belchenko
Don't do normpath after abspath, because this function is called inside abspath
739
        if win32utils.winver == 'Windows 98':
740
            raise TestSkipped('Windows 98 cannot handle unicode filenames')
741
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
742
        try:
743
            os.mkdir(u'dod\xe9')
744
        except UnicodeError:
745
            raise TestSkipped('cannot create unicode directory')
746
747
        os.chdir(u'dod\xe9')
748
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
749
        # On Mac OSX this directory is actually:
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
750
        #   u'/dode\u0301' => '/dode\xcc\x81
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
751
        # but we should normalize it back to
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
752
        #   u'/dod\xe9' => '/dod\xc3\xa9'
753
        url = urlutils.local_path_to_url('.')
754
        self.assertEndsWith(url, '/dod%C3%A9')
2512.4.1 by Ian Clatworthy
Fixes #115491 - 'branch lp:projname' now creates ./projname as exected
755
756
757
class TestDeriveToLocation(TestCase):
758
    """Test that the mapping of FROM_LOCATION to TO_LOCATION works."""
759
760
    def test_to_locations_derived_from_paths(self):
761
        derive = urlutils.derive_to_location
762
        self.assertEqual("bar", derive("bar"))
763
        self.assertEqual("bar", derive("../bar"))
764
        self.assertEqual("bar", derive("/foo/bar"))
765
        self.assertEqual("bar", derive("c:/foo/bar"))
766
        self.assertEqual("bar", derive("c:bar"))
767
768
    def test_to_locations_derived_from_urls(self):
769
        derive = urlutils.derive_to_location
770
        self.assertEqual("bar", derive("http://foo/bar"))
771
        self.assertEqual("bar", derive("bzr+ssh://foo/bar"))
772
        self.assertEqual("foo-bar", derive("lp:foo-bar"))
3242.3.26 by Aaron Bentley
Implement rebase_url
773
774
775
class TestRebaseURL(TestCase):
776
    """Test the behavior of rebase_url."""
777
778
    def test_non_relative(self):
779
        result = urlutils.rebase_url('file://foo', 'file://foo',
780
                                     'file://foo/bar')
781
        self.assertEqual('file://foo', result)
782
        result = urlutils.rebase_url('/foo', 'file://foo',
783
                                     'file://foo/bar')
784
        self.assertEqual('/foo', result)
785
3242.3.36 by Aaron Bentley
Updates from review comments
786
    def test_different_ports(self):
787
        e = self.assertRaises(InvalidRebaseURLs, urlutils.rebase_url,
788
                              'foo', 'http://bar:80', 'http://bar:81')
789
        self.assertEqual(str(e), "URLs differ by more than path:"
790
                         " 'http://bar:80' and 'http://bar:81'")
791
792
    def test_different_hosts(self):
3242.3.33 by Aaron Bentley
Handle relative URL stacking cleanly
793
        e = self.assertRaises(InvalidRebaseURLs, urlutils.rebase_url,
794
                              'foo', 'http://bar', 'http://baz')
795
        self.assertEqual(str(e), "URLs differ by more than path: 'http://bar'"
796
                         " and 'http://baz'")
3242.3.26 by Aaron Bentley
Implement rebase_url
797
3242.3.36 by Aaron Bentley
Updates from review comments
798
    def test_different_protocol(self):
799
        e = self.assertRaises(InvalidRebaseURLs, urlutils.rebase_url,
800
                              'foo', 'http://bar', 'ftp://bar')
801
        self.assertEqual(str(e), "URLs differ by more than path: 'http://bar'"
802
                         " and 'ftp://bar'")
803
3242.3.26 by Aaron Bentley
Implement rebase_url
804
    def test_rebase_success(self):
805
        self.assertEqual('../bar', urlutils.rebase_url('bar', 'http://baz/',
806
                         'http://baz/qux'))
807
        self.assertEqual('qux/bar', urlutils.rebase_url('bar',
808
                         'http://baz/qux', 'http://baz/'))
809
        self.assertEqual('.', urlutils.rebase_url('foo',
810
                         'http://bar/', 'http://bar/foo/'))
3567.2.1 by Michael Hudson
urlutils.rebase_url handles '..' path segments in 'url'
811
        self.assertEqual('qux/bar', urlutils.rebase_url('../bar',
812
                         'http://baz/qux/foo', 'http://baz/'))
3242.3.26 by Aaron Bentley
Implement rebase_url
813
814
    def test_determine_relative_path(self):
815
        self.assertEqual('../../baz/bar',
816
                         urlutils.determine_relative_path(
817
                         '/qux/quxx', '/baz/bar'))
818
        self.assertEqual('..',
819
                         urlutils.determine_relative_path(
820
                         '/bar/baz', '/bar'))
821
        self.assertEqual('baz',
822
                         urlutils.determine_relative_path(
823
                         '/bar', '/bar/baz'))
824
        self.assertEqual('.', urlutils.determine_relative_path(
825
                         '/bar', '/bar'))
3873.3.1 by Martin Pool
Move Transport._split_url to urlutils, and ad a simple test
826
827
828
class TestParseURL(TestCase):
829
6055.2.1 by Jelmer Vernooij
Add UnparsedUrl.
830
    def test_parse_simple(self):
831
        parsed = urlutils.parse_url('http://example.com:80/one')
6055.2.6 by Jelmer Vernooij
Split out parse_url.
832
        self.assertEquals(('http', None, None, 'example.com', 80, '/one'),
833
            parsed)
6055.2.1 by Jelmer Vernooij
Add UnparsedUrl.
834
835
    def test_ipv6(self):
836
        parsed = urlutils.parse_url('http://[1:2:3::40]/one')
6055.2.6 by Jelmer Vernooij
Split out parse_url.
837
        self.assertEquals(('http', None, None, '1:2:3::40', None, '/one'),
838
            parsed)
6055.2.1 by Jelmer Vernooij
Add UnparsedUrl.
839
840
    def test_ipv6_port(self):
841
        parsed = urlutils.parse_url('http://[1:2:3::40]:80/one')
6055.2.6 by Jelmer Vernooij
Split out parse_url.
842
        self.assertEquals(('http', None, None, '1:2:3::40', 80, '/one'),
843
            parsed)
6055.2.7 by Jelmer Vernooij
Change parse_url to URL.from_string.
844
845
846
class TestURL(TestCase):
847
848
    def test_parse_simple(self):
849
        parsed = urlutils.URL.from_string('http://example.com:80/one')
850
        self.assertEquals('http', parsed.scheme)
851
        self.assertIs(None, parsed.user)
852
        self.assertIs(None, parsed.password)
853
        self.assertEquals('example.com', parsed.host)
854
        self.assertEquals(80, parsed.port)
855
        self.assertEquals('/one', parsed.path)
856
857
    def test_ipv6(self):
858
        parsed = urlutils.URL.from_string('http://[1:2:3::40]/one')
859
        self.assertEquals('http', parsed.scheme)
860
        self.assertIs(None, parsed.port)
861
        self.assertIs(None, parsed.user)
862
        self.assertIs(None, parsed.password)
863
        self.assertEquals('1:2:3::40', parsed.host)
864
        self.assertEquals('/one', parsed.path)
865
866
    def test_ipv6_port(self):
867
        parsed = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
868
        self.assertEquals('http', parsed.scheme)
869
        self.assertEquals('1:2:3::40', parsed.host)
870
        self.assertIs(None, parsed.user)
871
        self.assertIs(None, parsed.password)
872
        self.assertEquals(80, parsed.port)
873
        self.assertEquals('/one', parsed.path)
874
875
    def test_quoted(self):
876
        parsed = urlutils.URL.from_string(
877
            'http://ro%62ey:h%40t@ex%41mple.com:2222/path')
878
        self.assertEquals(parsed.quoted_host, 'ex%41mple.com')
879
        self.assertEquals(parsed.host, 'exAmple.com')
880
        self.assertEquals(parsed.port, 2222)
881
        self.assertEquals(parsed.quoted_user, 'ro%62ey')
882
        self.assertEquals(parsed.user, 'robey')
883
        self.assertEquals(parsed.quoted_password, 'h%40t')
884
        self.assertEquals(parsed.password, 'h@t')
885
        self.assertEquals(parsed.path, '/path')
6055.2.8 by Jelmer Vernooij
Add repr()
886
887
    def test_eq(self):
888
        parsed1 = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
889
        parsed2 = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
890
        self.assertEquals(parsed1, parsed2)
891
        self.assertEquals(parsed1, parsed1)
892
        parsed2.path = '/two'
6055.2.11 by Jelmer Vernooij
Fix tests.
893
        self.assertNotEquals(parsed1, parsed2)
6055.2.8 by Jelmer Vernooij
Add repr()
894
895
    def test_repr(self):
896
        parsed = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
6055.2.11 by Jelmer Vernooij
Fix tests.
897
        self.assertEquals(
898
            "<URL('http', None, None, '1:2:3::40', 80, '/one')>",
6055.2.8 by Jelmer Vernooij
Add repr()
899
            repr(parsed))
900
6055.2.13 by Jelmer Vernooij
Add URL.__str__.
901
    def test_str(self):
902
        parsed = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
903
        self.assertEquals('http://[1:2:3::40]:80/one', str(parsed))
904
6055.2.15 by Jelmer Vernooij
Add URL._combine_paths.
905
    def test__combine_paths(self):
906
        combine = urlutils.URL._combine_paths
907
        self.assertEqual('/home/sarah/project/foo',
908
                         combine('/home/sarah', 'project/foo'))
909
        self.assertEqual('/etc',
910
                         combine('/home/sarah', '../../etc'))
911
        self.assertEqual('/etc',
912
                         combine('/home/sarah', '../../../etc'))
913
        self.assertEqual('/etc',
914
                         combine('/home/sarah', '/etc'))
6055.2.17 by Jelmer Vernooij
Add URL.clone().
915
916
    def test_clone(self):
917
        url = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
918
        url1 = url.clone("two")
919
        self.assertEquals("/one/two", url1.path)
920
        url2 = url.clone("/two")
921
        self.assertEquals("/two", url2.path)
922
        url3 = url.clone()
923
        self.assertIsNot(url, url3)
924
        self.assertEquals(url, url3)
6240.4.2 by Jelmer Vernooij
Moar tests.
925
926
927
class TestFileRelpath(TestCase):
928
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
929
    # GZ 2011-11-18: A way to override all path handling functions to one
930
    #                platform or another for testing would be nice.
931
932
    def _with_posix_paths(self):
933
        self.overrideAttr(urlutils, "local_path_from_url",
934
            urlutils._posix_local_path_from_url)
935
        self.overrideAttr(urlutils, "MIN_ABS_FILEURL_LENGTH", len("file:///"))
936
        self.overrideAttr(osutils, "normpath", osutils._posix_normpath)
937
        self.overrideAttr(osutils, "abspath", osutils._posix_abspath)
938
        self.overrideAttr(osutils, "normpath", osutils._posix_normpath)
939
        self.overrideAttr(osutils, "pathjoin", osutils.posixpath.join)
940
        self.overrideAttr(osutils, "split", osutils.posixpath.split)
941
        self.overrideAttr(osutils, "MIN_ABS_PATHLENGTH", 1)
942
943
    def _with_win32_paths(self):
944
        self.overrideAttr(urlutils, "local_path_from_url",
945
            urlutils._win32_local_path_from_url)
946
        self.overrideAttr(urlutils, "MIN_ABS_FILEURL_LENGTH",
947
            urlutils.WIN32_MIN_ABS_FILEURL_LENGTH)
948
        self.overrideAttr(osutils, "abspath", osutils._win32_abspath)
949
        self.overrideAttr(osutils, "normpath", osutils._win32_normpath)
950
        self.overrideAttr(osutils, "pathjoin", osutils._win32_pathjoin)
951
        self.overrideAttr(osutils, "split", osutils.ntpath.split)
952
        self.overrideAttr(osutils, "MIN_ABS_PATHLENGTH", 3)
953
954
    def test_same_url_posix(self):
955
        self._with_posix_paths()
6240.4.2 by Jelmer Vernooij
Moar tests.
956
        self.assertEquals("",
957
            urlutils.file_relpath("file:///a", "file:///a"))
958
        self.assertEquals("",
959
            urlutils.file_relpath("file:///a", "file:///a/"))
960
        self.assertEquals("",
961
            urlutils.file_relpath("file:///a/", "file:///a"))
962
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
963
    def test_same_url_win32(self):
964
        self._with_win32_paths()
965
        self.assertEquals("",
966
            urlutils.file_relpath("file:///A:/", "file:///A:/"))
967
        self.assertEquals("",
968
            urlutils.file_relpath("file:///A|/", "file:///A:/"))
969
        self.assertEquals("",
970
            urlutils.file_relpath("file:///A:/b/", "file:///A:/b/"))
971
        self.assertEquals("",
972
            urlutils.file_relpath("file:///A:/b", "file:///A:/b/"))
973
        self.assertEquals("",
974
            urlutils.file_relpath("file:///A:/b/", "file:///A:/b"))
975
976
    def test_child_posix(self):
977
        self._with_posix_paths()
6240.4.2 by Jelmer Vernooij
Moar tests.
978
        self.assertEquals("b",
979
            urlutils.file_relpath("file:///a", "file:///a/b"))
980
        self.assertEquals("b",
981
            urlutils.file_relpath("file:///a/", "file:///a/b"))
982
        self.assertEquals("b/c",
983
            urlutils.file_relpath("file:///a", "file:///a/b/c"))
984
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
985
    def test_child_win32(self):
986
        self._with_win32_paths()
987
        self.assertEquals("b",
988
            urlutils.file_relpath("file:///A:/", "file:///A:/b"))
989
        self.assertEquals("b",
990
            urlutils.file_relpath("file:///A|/", "file:///A:/b"))
991
        self.assertEquals("c",
992
            urlutils.file_relpath("file:///A:/b", "file:///A:/b/c"))
993
        self.assertEquals("c",
994
            urlutils.file_relpath("file:///A:/b/", "file:///A:/b/c"))
995
        self.assertEquals("c/d",
996
            urlutils.file_relpath("file:///A:/b", "file:///A:/b/c/d"))
997
998
    def test_sibling_posix(self):
999
        self._with_posix_paths()
6240.4.2 by Jelmer Vernooij
Moar tests.
1000
        self.assertRaises(PathNotChild,
1001
            urlutils.file_relpath, "file:///a/b", "file:///a/c")
1002
        self.assertRaises(PathNotChild,
1003
            urlutils.file_relpath, "file:///a/b/", "file:///a/c")
1004
        self.assertRaises(PathNotChild,
1005
            urlutils.file_relpath, "file:///a/b/", "file:///a/c/")
1006
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
1007
    def test_sibling_win32(self):
1008
        self._with_win32_paths()
1009
        self.assertRaises(PathNotChild,
1010
            urlutils.file_relpath, "file:///A:/b", "file:///A:/c")
1011
        self.assertRaises(PathNotChild,
1012
            urlutils.file_relpath, "file:///A:/b/", "file:///A:/c")
1013
        self.assertRaises(PathNotChild,
1014
            urlutils.file_relpath, "file:///A:/b/", "file:///A:/c/")
1015
1016
    def test_parent_posix(self):
1017
        self._with_posix_paths()
6240.4.2 by Jelmer Vernooij
Moar tests.
1018
        self.assertRaises(PathNotChild,
1019
            urlutils.file_relpath, "file:///a/b", "file:///a")
1020
        self.assertRaises(PathNotChild,
1021
            urlutils.file_relpath, "file:///a/b", "file:///a/")
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
1022
1023
    def test_parent_win32(self):
1024
        self._with_win32_paths()
1025
        self.assertRaises(PathNotChild,
1026
            urlutils.file_relpath, "file:///A:/b", "file:///A:/")
1027
        self.assertRaises(PathNotChild,
1028
            urlutils.file_relpath, "file:///A:/b/c", "file:///A:/b")
6379.4.4 by Jelmer Vernooij
Add some tests.
1029
1030
1031
class QuoteTests(TestCase):
1032
1033
    def test_quote(self):
1034
        self.assertEqual('abc%20def', urlutils.quote('abc def'))
1035
        self.assertEqual('abc%2Fdef', urlutils.quote('abc/def', safe=''))
1036
        self.assertEqual('abc/def', urlutils.quote('abc/def', safe='/'))
1037
1038
    def test_quote_tildes(self):
1039
        self.assertEqual('%7Efoo', urlutils.quote('~foo'))
1040
        self.assertEqual('~foo', urlutils.quote('~foo', safe='/~'))
1041
1042
    def test_unquote(self):
1043
        self.assertEqual('%', urlutils.unquote('%25'))
1044
        self.assertEqual('\xc3\xa5', urlutils.unquote('%C3%A5'))
1045
        self.assertEqual(u"\xe5", urlutils.unquote(u'\xe5'))