1
# Copyright (C) 2005 Canonical Ltd
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.
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.
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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
"""Tests for the urlutils wrapper."""
23
from bzrlib import osutils, urlutils, win32utils
25
from bzrlib.errors import InvalidURL, InvalidURLJoin
26
from bzrlib.tests import TestCaseInTempDir, TestCase, TestSkipped
29
class TestUrlToPath(TestCase):
31
def test_basename(self):
32
# bzrlib.urlutils.basename
33
# Test bzrlib.urlutils.split()
34
basename = urlutils.basename
35
if sys.platform == 'win32':
36
self.assertRaises(InvalidURL, basename, 'file:///path/to/foo')
37
self.assertEqual('foo', basename('file:///C|/foo'))
38
self.assertEqual('foo', basename('file:///C:/foo'))
39
self.assertEqual('', basename('file:///C:/'))
41
self.assertEqual('foo', basename('file:///foo'))
42
self.assertEqual('', basename('file:///'))
44
self.assertEqual('foo', basename('http://host/path/to/foo'))
45
self.assertEqual('foo', basename('http://host/path/to/foo/'))
47
basename('http://host/path/to/foo/', exclude_trailing_slash=False))
48
self.assertEqual('path', basename('http://host/path'))
49
self.assertEqual('', basename('http://host/'))
50
self.assertEqual('', basename('http://host'))
51
self.assertEqual('path', basename('http:///nohost/path'))
53
self.assertEqual('path', basename('random+scheme://user:pass@ahost:port/path'))
54
self.assertEqual('path', basename('random+scheme://user:pass@ahost:port/path/'))
55
self.assertEqual('', basename('random+scheme://user:pass@ahost:port/'))
58
self.assertEqual('foo', basename('path/to/foo'))
59
self.assertEqual('foo', basename('path/to/foo/'))
60
self.assertEqual('', basename('path/to/foo/',
61
exclude_trailing_slash=False))
62
self.assertEqual('foo', basename('path/../foo'))
63
self.assertEqual('foo', basename('../path/foo'))
65
def test_normalize_url_files(self):
66
# Test that local paths are properly normalized
67
normalize_url = urlutils.normalize_url
69
def norm_file(expected, path):
70
url = normalize_url(path)
71
self.assertStartsWith(url, 'file:///')
72
if sys.platform == 'win32':
73
url = url[len('file:///C:'):]
75
url = url[len('file://'):]
77
self.assertEndsWith(url, expected)
79
norm_file('path/to/foo', 'path/to/foo')
80
norm_file('/path/to/foo', '/path/to/foo')
81
norm_file('path/to/foo', '../path/to/foo')
83
# Local paths are assumed to *not* be escaped at all
85
u'uni/\xb5'.encode(bzrlib.user_encoding)
87
# locale cannot handle unicode
90
norm_file('uni/%C2%B5', u'uni/\xb5')
92
norm_file('uni/%25C2%25B5', u'uni/%C2%B5')
93
norm_file('uni/%20b', u'uni/ b')
94
# All the crazy characters get escaped in local paths => file:/// urls
95
# The ' ' character must not be at the end, because on win32
96
# it gets stripped off by ntpath.abspath
97
norm_file('%27%20%3B/%3F%3A%40%26%3D%2B%24%2C%23', "' ;/?:@&=+$,#")
99
def test_normalize_url_hybrid(self):
100
# Anything with a scheme:// should be treated as a hybrid url
101
# which changes what characters get escaped.
102
normalize_url = urlutils.normalize_url
104
eq = self.assertEqual
105
eq('file:///foo/', normalize_url(u'file:///foo/'))
106
eq('file:///foo/%20', normalize_url(u'file:///foo/ '))
107
eq('file:///foo/%20', normalize_url(u'file:///foo/%20'))
108
# Don't escape reserved characters
109
eq('file:///ab_c.d-e/%f:?g&h=i+j;k,L#M$',
110
normalize_url('file:///ab_c.d-e/%f:?g&h=i+j;k,L#M$'))
111
eq('http://ab_c.d-e/%f:?g&h=i+j;k,L#M$',
112
normalize_url('http://ab_c.d-e/%f:?g&h=i+j;k,L#M$'))
114
# Escape unicode characters, but not already escaped chars
115
eq('http://host/ab/%C2%B5/%C2%B5',
116
normalize_url(u'http://host/ab/%C2%B5/\xb5'))
118
# Normalize verifies URLs when they are not unicode
119
# (indicating they did not come from the user)
120
self.assertRaises(InvalidURL, normalize_url, 'http://host/\xb5')
121
self.assertRaises(InvalidURL, normalize_url, 'http://host/ ')
123
def test_url_scheme_re(self):
124
# Test paths that may be URLs
125
def test_one(url, scheme_and_path):
126
"""Assert that _url_scheme_re correctly matches
128
:param scheme_and_path: The (scheme, path) that should be matched
129
can be None, to indicate it should not match
131
m = urlutils._url_scheme_re.match(url)
132
if scheme_and_path is None:
133
self.assertEqual(None, m)
135
self.assertEqual(scheme_and_path[0], m.group('scheme'))
136
self.assertEqual(scheme_and_path[1], m.group('path'))
139
test_one('/path', None)
140
test_one('C:/path', None)
141
test_one('../path/to/foo', None)
142
test_one(u'../path/to/fo\xe5', None)
145
test_one('http://host/path/', ('http', 'host/path/'))
146
test_one('sftp://host/path/to/foo', ('sftp', 'host/path/to/foo'))
147
test_one('file:///usr/bin', ('file', '/usr/bin'))
148
test_one('file:///C:/Windows', ('file', '/C:/Windows'))
149
test_one('file:///C|/Windows', ('file', '/C|/Windows'))
150
test_one(u'readonly+sftp://host/path/\xe5', ('readonly+sftp', u'host/path/\xe5'))
153
# Can't have slashes or colons in the scheme
154
test_one('/path/to/://foo', None)
155
test_one('path:path://foo', None)
156
# Must have more than one character for scheme
157
test_one('C://foo', None)
158
test_one('ab://foo', ('ab', 'foo'))
160
def test_dirname(self):
161
# Test bzrlib.urlutils.dirname()
162
dirname = urlutils.dirname
163
if sys.platform == 'win32':
164
self.assertRaises(InvalidURL, dirname, 'file:///path/to/foo')
165
self.assertEqual('file:///C|/', dirname('file:///C|/foo'))
166
self.assertEqual('file:///C|/', dirname('file:///C|/'))
168
self.assertEqual('file:///', dirname('file:///foo'))
169
self.assertEqual('file:///', dirname('file:///'))
171
self.assertEqual('http://host/path/to', dirname('http://host/path/to/foo'))
172
self.assertEqual('http://host/path/to', dirname('http://host/path/to/foo/'))
173
self.assertEqual('http://host/path/to/foo',
174
dirname('http://host/path/to/foo/', exclude_trailing_slash=False))
175
self.assertEqual('http://host/', dirname('http://host/path'))
176
self.assertEqual('http://host/', dirname('http://host/'))
177
self.assertEqual('http://host', dirname('http://host'))
178
self.assertEqual('http:///nohost', dirname('http:///nohost/path'))
180
self.assertEqual('random+scheme://user:pass@ahost:port/',
181
dirname('random+scheme://user:pass@ahost:port/path'))
182
self.assertEqual('random+scheme://user:pass@ahost:port/',
183
dirname('random+scheme://user:pass@ahost:port/path/'))
184
self.assertEqual('random+scheme://user:pass@ahost:port/',
185
dirname('random+scheme://user:pass@ahost:port/'))
188
self.assertEqual('path/to', dirname('path/to/foo'))
189
self.assertEqual('path/to', dirname('path/to/foo/'))
190
self.assertEqual('path/to/foo',
191
dirname('path/to/foo/', exclude_trailing_slash=False))
192
self.assertEqual('path/..', dirname('path/../foo'))
193
self.assertEqual('../path', dirname('../path/foo'))
196
def test(expected, *args):
197
joined = urlutils.join(*args)
198
self.assertEqual(expected, joined)
200
# Test relative path joining
201
test('foo', 'foo') # relative fragment with nothing is preserved.
202
test('foo/bar', 'foo', 'bar')
203
test('http://foo/bar', 'http://foo', 'bar')
204
test('http://foo/bar', 'http://foo', '.', 'bar')
205
test('http://foo/baz', 'http://foo', 'bar', '../baz')
206
test('http://foo/bar/baz', 'http://foo', 'bar/baz')
207
test('http://foo/baz', 'http://foo', 'bar/../baz')
208
test('http://foo/baz', 'http://foo/bar/', '../baz')
211
test('http://foo', 'http://foo') # abs url with nothing is preserved.
212
test('http://bar', 'http://foo', 'http://bar')
213
test('sftp://bzr/foo', 'http://foo', 'bar', 'sftp://bzr/foo')
214
test('file:///bar', 'foo', 'file:///bar')
215
test('http://bar/', 'http://foo', 'http://bar/')
216
test('http://bar/a', 'http://foo', 'http://bar/a')
217
test('http://bar/a/', 'http://foo', 'http://bar/a/')
220
test('file:///foo', 'file:///', 'foo')
221
test('file:///bar/foo', 'file:///bar/', 'foo')
222
test('http://host/foo', 'http://host/', 'foo')
223
test('http://host/', 'http://host', '')
226
# Cannot go above root
227
# Implicitly at root:
228
self.assertRaises(InvalidURLJoin, urlutils.join,
229
'http://foo', '../baz')
230
self.assertRaises(InvalidURLJoin, urlutils.join,
232
# Joining from a path explicitly under the root.
233
self.assertRaises(InvalidURLJoin, urlutils.join,
234
'http://foo/a', '../../b')
236
def test_joinpath(self):
237
def test(expected, *args):
238
joined = urlutils.joinpath(*args)
239
self.assertEqual(expected, joined)
241
# Test a single element
244
# Test relative path joining
245
test('foo/bar', 'foo', 'bar')
246
test('foo/bar', 'foo', '.', 'bar')
247
test('foo/baz', 'foo', 'bar', '../baz')
248
test('foo/bar/baz', 'foo', 'bar/baz')
249
test('foo/baz', 'foo', 'bar/../baz')
251
# Test joining to an absolute path
253
test('/foo', '/foo', '.')
254
test('/foo/bar', '/foo', 'bar')
255
test('/', '/foo', '..')
257
# Test joining with an absolute path
258
test('/bar', 'foo', '/bar')
260
# Test joining to a path with a trailing slash
261
test('foo/bar', 'foo/', 'bar')
264
# Cannot go above root
265
self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '../baz')
266
self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '..')
267
self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '/..')
269
def test_function_type(self):
270
if sys.platform == 'win32':
271
self.assertEqual(urlutils._win32_local_path_to_url, urlutils.local_path_to_url)
272
self.assertEqual(urlutils._win32_local_path_from_url, urlutils.local_path_from_url)
274
self.assertEqual(urlutils._posix_local_path_to_url, urlutils.local_path_to_url)
275
self.assertEqual(urlutils._posix_local_path_from_url, urlutils.local_path_from_url)
277
def test_posix_local_path_to_url(self):
278
to_url = urlutils._posix_local_path_to_url
279
self.assertEqual('file:///path/to/foo',
280
to_url('/path/to/foo'))
283
result = to_url(u'/path/to/r\xe4ksm\xf6rg\xe5s')
285
raise TestSkipped("local encoding cannot handle unicode")
287
self.assertEqual('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
289
def test_posix_local_path_from_url(self):
290
from_url = urlutils._posix_local_path_from_url
291
self.assertEqual('/path/to/foo',
292
from_url('file:///path/to/foo'))
293
self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
294
from_url('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
295
self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
296
from_url('file:///path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
298
self.assertRaises(InvalidURL, from_url, '/path/to/foo')
300
def test_win32_local_path_to_url(self):
301
to_url = urlutils._win32_local_path_to_url
302
self.assertEqual('file:///C:/path/to/foo',
303
to_url('C:/path/to/foo'))
304
# BOGUS: on win32, ntpath.abspath will strip trailing
305
# whitespace, so this will always fail
306
# Though under linux, it fakes abspath support
307
# and thus will succeed
308
# self.assertEqual('file:///C:/path/to/foo%20',
309
# to_url('C:/path/to/foo '))
310
self.assertEqual('file:///C:/path/to/f%20oo',
311
to_url('C:/path/to/f oo'))
314
result = to_url(u'd:/path/to/r\xe4ksm\xf6rg\xe5s')
316
raise TestSkipped("local encoding cannot handle unicode")
318
self.assertEqual('file:///D:/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
320
def test_win32_unc_path_to_url(self):
321
to_url = urlutils._win32_local_path_to_url
322
self.assertEqual('file://HOST/path',
323
to_url(r'\\HOST\path'))
324
self.assertEqual('file://HOST/path',
325
to_url('//HOST/path'))
328
result = to_url(u'//HOST/path/to/r\xe4ksm\xf6rg\xe5s')
330
raise TestSkipped("local encoding cannot handle unicode")
332
self.assertEqual('file://HOST/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
335
def test_win32_local_path_from_url(self):
336
from_url = urlutils._win32_local_path_from_url
337
self.assertEqual('C:/path/to/foo',
338
from_url('file:///C|/path/to/foo'))
339
self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
340
from_url('file:///d|/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
341
self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
342
from_url('file:///d:/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
344
self.assertRaises(InvalidURL, from_url, '/path/to/foo')
345
# Not a valid _win32 url, no drive letter
346
self.assertRaises(InvalidURL, from_url, 'file:///path/to/foo')
348
def test_win32_unc_path_from_url(self):
349
from_url = urlutils._win32_local_path_from_url
350
self.assertEqual('//HOST/path', from_url('file://HOST/path'))
351
# despite IE allows 2, 4, 5 and 6 slashes in URL to another machine
352
# we want to use only 2 slashes
353
# Firefox understand only 5 slashes in URL, but it's ugly
354
self.assertRaises(InvalidURL, from_url, 'file:////HOST/path')
355
self.assertRaises(InvalidURL, from_url, 'file://///HOST/path')
356
self.assertRaises(InvalidURL, from_url, 'file://////HOST/path')
357
# check for file://C:/ instead of file:///C:/
358
self.assertRaises(InvalidURL, from_url, 'file://C:/path')
360
def test_win32_extract_drive_letter(self):
361
extract = urlutils._win32_extract_drive_letter
362
self.assertEqual(('file:///C:', '/foo'), extract('file://', '/C:/foo'))
363
self.assertEqual(('file:///d|', '/path'), extract('file://', '/d|/path'))
364
self.assertRaises(InvalidURL, extract, 'file://', '/path')
366
def test_split(self):
367
# Test bzrlib.urlutils.split()
368
split = urlutils.split
369
if sys.platform == 'win32':
370
self.assertRaises(InvalidURL, split, 'file:///path/to/foo')
371
self.assertEqual(('file:///C|/', 'foo'), split('file:///C|/foo'))
372
self.assertEqual(('file:///C:/', ''), split('file:///C:/'))
374
self.assertEqual(('file:///', 'foo'), split('file:///foo'))
375
self.assertEqual(('file:///', ''), split('file:///'))
377
self.assertEqual(('http://host/path/to', 'foo'), split('http://host/path/to/foo'))
378
self.assertEqual(('http://host/path/to', 'foo'), split('http://host/path/to/foo/'))
379
self.assertEqual(('http://host/path/to/foo', ''),
380
split('http://host/path/to/foo/', exclude_trailing_slash=False))
381
self.assertEqual(('http://host/', 'path'), split('http://host/path'))
382
self.assertEqual(('http://host/', ''), split('http://host/'))
383
self.assertEqual(('http://host', ''), split('http://host'))
384
self.assertEqual(('http:///nohost', 'path'), split('http:///nohost/path'))
386
self.assertEqual(('random+scheme://user:pass@ahost:port/', 'path'),
387
split('random+scheme://user:pass@ahost:port/path'))
388
self.assertEqual(('random+scheme://user:pass@ahost:port/', 'path'),
389
split('random+scheme://user:pass@ahost:port/path/'))
390
self.assertEqual(('random+scheme://user:pass@ahost:port/', ''),
391
split('random+scheme://user:pass@ahost:port/'))
394
self.assertEqual(('path/to', 'foo'), split('path/to/foo'))
395
self.assertEqual(('path/to', 'foo'), split('path/to/foo/'))
396
self.assertEqual(('path/to/foo', ''),
397
split('path/to/foo/', exclude_trailing_slash=False))
398
self.assertEqual(('path/..', 'foo'), split('path/../foo'))
399
self.assertEqual(('../path', 'foo'), split('../path/foo'))
401
def test_win32_strip_local_trailing_slash(self):
402
strip = urlutils._win32_strip_local_trailing_slash
403
self.assertEqual('file://', strip('file://'))
404
self.assertEqual('file:///', strip('file:///'))
405
self.assertEqual('file:///C', strip('file:///C'))
406
self.assertEqual('file:///C:', strip('file:///C:'))
407
self.assertEqual('file:///d|', strip('file:///d|'))
408
self.assertEqual('file:///C:/', strip('file:///C:/'))
409
self.assertEqual('file:///C:/a', strip('file:///C:/a/'))
411
def test_strip_trailing_slash(self):
412
sts = urlutils.strip_trailing_slash
413
if sys.platform == 'win32':
414
self.assertEqual('file:///C|/', sts('file:///C|/'))
415
self.assertEqual('file:///C:/foo', sts('file:///C:/foo'))
416
self.assertEqual('file:///C|/foo', sts('file:///C|/foo/'))
418
self.assertEqual('file:///', sts('file:///'))
419
self.assertEqual('file:///foo', sts('file:///foo'))
420
self.assertEqual('file:///foo', sts('file:///foo/'))
422
self.assertEqual('http://host/', sts('http://host/'))
423
self.assertEqual('http://host/foo', sts('http://host/foo'))
424
self.assertEqual('http://host/foo', sts('http://host/foo/'))
426
# No need to fail just because the slash is missing
427
self.assertEqual('http://host', sts('http://host'))
428
# TODO: jam 20060502 Should this raise InvalidURL?
429
self.assertEqual('file://', sts('file://'))
431
self.assertEqual('random+scheme://user:pass@ahost:port/path',
432
sts('random+scheme://user:pass@ahost:port/path'))
433
self.assertEqual('random+scheme://user:pass@ahost:port/path',
434
sts('random+scheme://user:pass@ahost:port/path/'))
435
self.assertEqual('random+scheme://user:pass@ahost:port/',
436
sts('random+scheme://user:pass@ahost:port/'))
438
# Make sure relative paths work too
439
self.assertEqual('path/to/foo', sts('path/to/foo'))
440
self.assertEqual('path/to/foo', sts('path/to/foo/'))
441
self.assertEqual('../to/foo', sts('../to/foo/'))
442
self.assertEqual('path/../foo', sts('path/../foo/'))
444
def test_unescape_for_display_utf8(self):
445
# Test that URLs are converted to nice unicode strings for display
446
def test(expected, url, encoding='utf-8'):
447
disp_url = urlutils.unescape_for_display(url, encoding=encoding)
448
self.assertIsInstance(disp_url, unicode)
449
self.assertEqual(expected, disp_url)
451
test('http://foo', 'http://foo')
452
if sys.platform == 'win32':
453
test('C:/foo/path', 'file:///C|/foo/path')
454
test('C:/foo/path', 'file:///C:/foo/path')
456
test('/foo/path', 'file:///foo/path')
458
test('http://foo/%2Fbaz', 'http://foo/%2Fbaz')
459
test(u'http://host/r\xe4ksm\xf6rg\xe5s',
460
'http://host/r%C3%A4ksm%C3%B6rg%C3%A5s')
462
# Make sure special escaped characters stay escaped
463
test(u'http://host/%3B%2F%3F%3A%40%26%3D%2B%24%2C%23',
464
'http://host/%3B%2F%3F%3A%40%26%3D%2B%24%2C%23')
466
# Can we handle sections that don't have utf-8 encoding?
467
test(u'http://host/%EE%EE%EE/r\xe4ksm\xf6rg\xe5s',
468
'http://host/%EE%EE%EE/r%C3%A4ksm%C3%B6rg%C3%A5s')
470
# Test encoding into output that can handle some characters
471
test(u'http://host/%EE%EE%EE/r\xe4ksm\xf6rg\xe5s',
472
'http://host/%EE%EE%EE/r%C3%A4ksm%C3%B6rg%C3%A5s',
473
encoding='iso-8859-1')
475
# This one can be encoded into utf8
476
test(u'http://host/\u062c\u0648\u062c\u0648',
477
'http://host/%d8%ac%d9%88%d8%ac%d9%88',
480
# This can't be put into 8859-1 and so stays as escapes
481
test(u'http://host/%d8%ac%d9%88%d8%ac%d9%88',
482
'http://host/%d8%ac%d9%88%d8%ac%d9%88',
483
encoding='iso-8859-1')
485
def test_escape(self):
486
self.assertEqual('%25', urlutils.escape('%'))
487
self.assertEqual('%C3%A5', urlutils.escape(u'\xe5'))
489
def test_unescape(self):
490
self.assertEqual('%', urlutils.unescape('%25'))
491
self.assertEqual(u'\xe5', urlutils.unescape('%C3%A5'))
493
self.assertRaises(InvalidURL, urlutils.unescape, u'\xe5')
494
self.assertRaises(InvalidURL, urlutils.unescape, '\xe5')
495
self.assertRaises(InvalidURL, urlutils.unescape, '%E5')
497
def test_escape_unescape(self):
498
self.assertEqual(u'\xe5', urlutils.unescape(urlutils.escape(u'\xe5')))
499
self.assertEqual('%', urlutils.unescape(urlutils.escape('%')))
501
def test_relative_url(self):
502
def test(expected, base, other):
503
result = urlutils.relative_url(base, other)
504
self.assertEqual(expected, result)
506
test('a', 'http://host/', 'http://host/a')
507
test('http://entirely/different', 'sftp://host/branch',
508
'http://entirely/different')
509
test('../person/feature', 'http://host/branch/mainline',
510
'http://host/branch/person/feature')
511
test('..', 'http://host/branch', 'http://host/')
512
test('http://host2/branch', 'http://host1/branch', 'http://host2/branch')
513
test('.', 'http://host1/branch', 'http://host1/branch')
514
test('../../../branch/2b', 'file:///home/jelmer/foo/bar/2b',
515
'file:///home/jelmer/branch/2b')
516
test('../../branch/2b', 'sftp://host/home/jelmer/bar/2b',
517
'sftp://host/home/jelmer/branch/2b')
518
test('../../branch/feature/%2b', 'http://host/home/jelmer/bar/%2b',
519
'http://host/home/jelmer/branch/feature/%2b')
520
test('../../branch/feature/2b', 'http://host/home/jelmer/bar/2b/',
521
'http://host/home/jelmer/branch/feature/2b')
522
# relative_url should preserve a trailing slash
523
test('../../branch/feature/2b/', 'http://host/home/jelmer/bar/2b/',
524
'http://host/home/jelmer/branch/feature/2b/')
525
test('../../branch/feature/2b/', 'http://host/home/jelmer/bar/2b',
526
'http://host/home/jelmer/branch/feature/2b/')
528
# TODO: treat http://host as http://host/
529
# relative_url is typically called from a branch.base or
530
# transport.base which always ends with a /
531
#test('a', 'http://host', 'http://host/a')
532
test('http://host/a', 'http://host', 'http://host/a')
533
#test('.', 'http://host', 'http://host/')
534
test('http://host/', 'http://host', 'http://host/')
535
#test('.', 'http://host/', 'http://host')
536
test('http://host', 'http://host/', 'http://host')
539
class TestCwdToURL(TestCaseInTempDir):
540
"""Test that local_path_to_url works base on the cwd"""
543
# This test will fail if getcwd is not ascii
547
url = urlutils.local_path_to_url('.')
548
self.assertEndsWith(url, '/mytest')
550
def test_non_ascii(self):
551
if win32utils.winver == 'Windows 98':
552
raise TestSkipped('Windows 98 cannot handle unicode filenames')
557
raise TestSkipped('cannot create unicode directory')
561
# On Mac OSX this directory is actually:
562
# u'/dode\u0301' => '/dode\xcc\x81
563
# but we should normalize it back to
564
# u'/dod\xe9' => '/dod\xc3\xa9'
565
url = urlutils.local_path_to_url('.')
566
self.assertEndsWith(url, '/dod%C3%A9')