/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to breezy/tests/test_urlutils.py

  • Committer: Jelmer Vernooij
  • Date: 2018-11-16 23:15:15 UTC
  • mfrom: (7180 work)
  • mto: This revision was merged to the branch mainline in revision 7183.
  • Revision ID: jelmer@jelmer.uk-20181116231515-zqd2yn6kj8lfydyp
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
import os
20
20
import sys
21
21
 
22
 
from .. import osutils, urlutils, win32utils
 
22
from .. import osutils, urlutils
23
23
from ..errors import (
24
24
    PathNotChild,
25
25
    )
38
38
        basename = urlutils.basename
39
39
        if sys.platform == 'win32':
40
40
            self.assertRaises(urlutils.InvalidURL, basename,
41
 
                    'file:///path/to/foo')
 
41
                              'file:///path/to/foo')
42
42
            self.assertEqual('foo', basename('file:///C|/foo'))
43
43
            self.assertEqual('foo', basename('file:///C:/foo'))
44
44
            self.assertEqual('', basename('file:///C:/'))
48
48
 
49
49
        self.assertEqual('foo', basename('http://host/path/to/foo'))
50
50
        self.assertEqual('foo', basename('http://host/path/to/foo/'))
51
 
        self.assertEqual('',
52
 
            basename('http://host/path/to/foo/', exclude_trailing_slash=False))
 
51
        self.assertEqual(
 
52
            '', basename('http://host/path/to/foo/',
 
53
                         exclude_trailing_slash=False))
53
54
        self.assertEqual('path', basename('http://host/path'))
54
55
        self.assertEqual('', basename('http://host/'))
55
56
        self.assertEqual('', basename('http://host'))
56
57
        self.assertEqual('path', basename('http:///nohost/path'))
57
58
 
58
 
        self.assertEqual('path', basename('random+scheme://user:pass@ahost:port/path'))
59
 
        self.assertEqual('path', basename('random+scheme://user:pass@ahost:port/path/'))
 
59
        self.assertEqual('path', basename(
 
60
            'random+scheme://user:pass@ahost:port/path'))
 
61
        self.assertEqual('path', basename(
 
62
            'random+scheme://user:pass@ahost:port/path/'))
60
63
        self.assertEqual('', basename('random+scheme://user:pass@ahost:port/'))
61
64
 
62
65
        # relative paths
63
66
        self.assertEqual('foo', basename('path/to/foo'))
64
67
        self.assertEqual('foo', basename('path/to/foo/'))
65
68
        self.assertEqual('', basename('path/to/foo/',
66
 
            exclude_trailing_slash=False))
 
69
                                      exclude_trailing_slash=False))
67
70
        self.assertEqual('foo', basename('path/../foo'))
68
71
        self.assertEqual('foo', basename('../path/foo'))
69
72
 
122
125
 
123
126
        # Unescape characters that don't need to be escaped
124
127
        eq('http://host/~bob%2525-._',
125
 
                normalize_url('http://host/%7Ebob%2525%2D%2E%5F'))
 
128
           normalize_url('http://host/%7Ebob%2525%2D%2E%5F'))
126
129
        eq('http://host/~bob%2525-._',
127
 
                normalize_url(u'http://host/%7Ebob%2525%2D%2E%5F'))
 
130
           normalize_url(u'http://host/%7Ebob%2525%2D%2E%5F'))
128
131
 
129
132
        if not PY3:
130
133
            # On Python 2, normalize verifies URLs when they are not unicode
131
134
            # (indicating they did not come from the user)
132
135
            self.assertRaises(urlutils.InvalidURL, normalize_url,
133
 
                    b'http://host/\xb5')
134
 
            self.assertRaises(urlutils.InvalidURL, normalize_url, b'http://host/ ')
 
136
                              b'http://host/\xb5')
 
137
            self.assertRaises(urlutils.InvalidURL,
 
138
                              normalize_url, b'http://host/ ')
135
139
 
136
140
    def test_url_scheme_re(self):
137
141
        # Test paths that may be URLs
160
164
        test_one('file:///usr/bin', ('file', '/usr/bin'))
161
165
        test_one('file:///C:/Windows', ('file', '/C:/Windows'))
162
166
        test_one('file:///C|/Windows', ('file', '/C|/Windows'))
163
 
        test_one(u'readonly+sftp://host/path/\xe5', ('readonly+sftp', u'host/path/\xe5'))
 
167
        test_one(u'readonly+sftp://host/path/\xe5',
 
168
                 ('readonly+sftp', u'host/path/\xe5'))
164
169
 
165
170
        # Weird stuff
166
171
        # Can't have slashes or colons in the scheme
175
180
        dirname = urlutils.dirname
176
181
        if sys.platform == 'win32':
177
182
            self.assertRaises(urlutils.InvalidURL, dirname,
178
 
                'file:///path/to/foo')
 
183
                              'file:///path/to/foo')
179
184
            self.assertEqual('file:///C|/', dirname('file:///C|/foo'))
180
185
            self.assertEqual('file:///C|/', dirname('file:///C|/'))
181
186
        else:
182
187
            self.assertEqual('file:///', dirname('file:///foo'))
183
188
            self.assertEqual('file:///', dirname('file:///'))
184
189
 
185
 
        self.assertEqual('http://host/path/to', dirname('http://host/path/to/foo'))
186
 
        self.assertEqual('http://host/path/to', dirname('http://host/path/to/foo/'))
 
190
        self.assertEqual('http://host/path/to',
 
191
                         dirname('http://host/path/to/foo'))
 
192
        self.assertEqual('http://host/path/to',
 
193
                         dirname('http://host/path/to/foo/'))
187
194
        self.assertEqual('http://host/path/to/foo',
188
 
            dirname('http://host/path/to/foo/', exclude_trailing_slash=False))
 
195
                         dirname('http://host/path/to/foo/',
 
196
                                 exclude_trailing_slash=False))
189
197
        self.assertEqual('http://host/', dirname('http://host/path'))
190
198
        self.assertEqual('http://host/', dirname('http://host/'))
191
199
        self.assertEqual('http://host', dirname('http://host'))
192
200
        self.assertEqual('http:///nohost', dirname('http:///nohost/path'))
193
201
 
194
202
        self.assertEqual('random+scheme://user:pass@ahost:port/',
195
 
            dirname('random+scheme://user:pass@ahost:port/path'))
196
 
        self.assertEqual('random+scheme://user:pass@ahost:port/',
197
 
            dirname('random+scheme://user:pass@ahost:port/path/'))
198
 
        self.assertEqual('random+scheme://user:pass@ahost:port/',
199
 
            dirname('random+scheme://user:pass@ahost:port/'))
 
203
                         dirname('random+scheme://user:pass@ahost:port/path'))
 
204
        self.assertEqual('random+scheme://user:pass@ahost:port/',
 
205
                         dirname('random+scheme://user:pass@ahost:port/path/'))
 
206
        self.assertEqual('random+scheme://user:pass@ahost:port/',
 
207
                         dirname('random+scheme://user:pass@ahost:port/'))
200
208
 
201
209
        # relative paths
202
210
        self.assertEqual('path/to', dirname('path/to/foo'))
203
211
        self.assertEqual('path/to', dirname('path/to/foo/'))
204
212
        self.assertEqual('path/to/foo',
205
 
            dirname('path/to/foo/', exclude_trailing_slash=False))
 
213
                         dirname('path/to/foo/', exclude_trailing_slash=False))
206
214
        self.assertEqual('path/..', dirname('path/../foo'))
207
215
        self.assertEqual('../path', dirname('../path/foo'))
208
 
    
 
216
 
209
217
    def test_is_url(self):
210
218
        self.assertTrue(urlutils.is_url('http://foo/bar'))
211
219
        self.assertTrue(urlutils.is_url('bzr+ssh://foo/bar'))
226
234
            self.assertEqual(expected, joined)
227
235
 
228
236
        # Test relative path joining
229
 
        test('foo', 'foo') # relative fragment with nothing is preserved.
 
237
        test('foo', 'foo')  # relative fragment with nothing is preserved.
230
238
        test('foo/bar', 'foo', 'bar')
231
239
        test('http://foo/bar', 'http://foo', 'bar')
232
240
        test('http://foo/bar', 'http://foo', '.', 'bar')
238
246
        test('lp:foo/bar/baz', 'lp:foo', 'bar/baz')
239
247
 
240
248
        # Absolute paths
241
 
        test('http://foo', 'http://foo') # abs url with nothing is preserved.
 
249
        test('http://foo', 'http://foo')  # abs url with nothing is preserved.
242
250
        test('http://bar', 'http://foo', 'http://bar')
243
251
        test('sftp://bzr/foo', 'http://foo', 'bar', 'sftp://bzr/foo')
244
252
        test('file:///bar', 'foo', 'file:///bar')
259
267
        # Cannot go above root
260
268
        # Implicitly at root:
261
269
        self.assertRaises(urlutils.InvalidURLJoin, urlutils.join,
262
 
                'http://foo', '../baz')
 
270
                          'http://foo', '../baz')
263
271
        self.assertRaises(urlutils.InvalidURLJoin, urlutils.join,
264
 
                'http://foo', '/..')
 
272
                          'http://foo', '/..')
265
273
        # Joining from a path explicitly under the root.
266
274
        self.assertRaises(urlutils.InvalidURLJoin, urlutils.join,
267
 
                'http://foo/a', '../../b')
 
275
                          'http://foo/a', '../../b')
268
276
 
269
277
    def test_joinpath(self):
270
278
        def test(expected, *args):
296
304
        # Invalid joinings
297
305
        # Cannot go above root
298
306
        self.assertRaises(urlutils.InvalidURLJoin, urlutils.joinpath, '/',
299
 
                '../baz')
300
 
        self.assertRaises(urlutils.InvalidURLJoin, urlutils.joinpath, '/',
301
 
                '..')
302
 
        self.assertRaises(urlutils.InvalidURLJoin, urlutils.joinpath, '/',
303
 
                '/..')
 
307
                          '../baz')
 
308
        self.assertRaises(urlutils.InvalidURLJoin, urlutils.joinpath, '/',
 
309
                          '..')
 
310
        self.assertRaises(urlutils.InvalidURLJoin, urlutils.joinpath, '/',
 
311
                          '/..')
304
312
 
305
313
    def test_join_segment_parameters_raw(self):
306
314
        join_segment_parameters_raw = urlutils.join_segment_parameters_raw
307
 
        self.assertEqual("/somedir/path", 
308
 
            join_segment_parameters_raw("/somedir/path"))
309
 
        self.assertEqual("/somedir/path,rawdata", 
310
 
            join_segment_parameters_raw("/somedir/path", "rawdata"))
 
315
        self.assertEqual("/somedir/path",
 
316
                         join_segment_parameters_raw("/somedir/path"))
 
317
        self.assertEqual("/somedir/path,rawdata",
 
318
                         join_segment_parameters_raw(
 
319
                             "/somedir/path", "rawdata"))
311
320
        self.assertRaises(urlutils.InvalidURLJoin,
312
 
            join_segment_parameters_raw, "/somedir/path",
313
 
                "rawdata1,rawdata2,rawdata3")
 
321
                          join_segment_parameters_raw, "/somedir/path",
 
322
                          "rawdata1,rawdata2,rawdata3")
314
323
        self.assertEqual("/somedir/path,bla,bar",
315
 
            join_segment_parameters_raw("/somedir/path", "bla", "bar"))
316
 
        self.assertEqual("/somedir,exist=some/path,bla,bar",
 
324
                         join_segment_parameters_raw(
 
325
                             "/somedir/path", "bla", "bar"))
 
326
        self.assertEqual(
 
327
            "/somedir,exist=some/path,bla,bar",
317
328
            join_segment_parameters_raw("/somedir,exist=some/path",
318
 
                "bla", "bar"))
319
 
        self.assertRaises(TypeError, join_segment_parameters_raw, 
320
 
            "/somepath", 42)
 
329
                                        "bla", "bar"))
 
330
        self.assertRaises(TypeError, join_segment_parameters_raw,
 
331
                          "/somepath", 42)
321
332
 
322
333
    def test_join_segment_parameters(self):
323
334
        join_segment_parameters = urlutils.join_segment_parameters
324
 
        self.assertEqual("/somedir/path", 
325
 
            join_segment_parameters("/somedir/path", {}))
326
 
        self.assertEqual("/somedir/path,key1=val1", 
 
335
        self.assertEqual("/somedir/path",
 
336
                         join_segment_parameters("/somedir/path", {}))
 
337
        self.assertEqual(
 
338
            "/somedir/path,key1=val1",
327
339
            join_segment_parameters("/somedir/path", {"key1": "val1"}))
328
340
        self.assertRaises(urlutils.InvalidURLJoin,
329
 
            join_segment_parameters, "/somedir/path",
330
 
            {"branch": "brr,brr,brr"})
331
 
        self.assertRaises(urlutils.InvalidURLJoin,
 
341
                          join_segment_parameters, "/somedir/path",
 
342
                          {"branch": "brr,brr,brr"})
 
343
        self.assertRaises(
 
344
            urlutils.InvalidURLJoin,
332
345
            join_segment_parameters, "/somedir/path", {"key1=val1": "val2"})
333
346
        self.assertEqual("/somedir/path,key1=val1,key2=val2",
334
 
            join_segment_parameters("/somedir/path", {
335
 
                "key1": "val1", "key2": "val2"}))
 
347
                         join_segment_parameters("/somedir/path", {
 
348
                             "key1": "val1", "key2": "val2"}))
336
349
        self.assertEqual("/somedir/path,key1=val1,key2=val2",
337
 
            join_segment_parameters("/somedir/path,key1=val1", {
338
 
                "key2": "val2"}))
 
350
                         join_segment_parameters("/somedir/path,key1=val1", {
 
351
                             "key2": "val2"}))
339
352
        self.assertEqual("/somedir/path,key1=val2",
340
 
            join_segment_parameters("/somedir/path,key1=val1", {
341
 
                "key1": "val2"}))
 
353
                         join_segment_parameters("/somedir/path,key1=val1", {
 
354
                             "key1": "val2"}))
342
355
        self.assertEqual("/somedir,exist=some/path,key1=val1",
343
 
            join_segment_parameters("/somedir,exist=some/path",
344
 
                {"key1": "val1"}))
345
 
        self.assertEqual("/,key1=val1,key2=val2",
 
356
                         join_segment_parameters("/somedir,exist=some/path",
 
357
                                                 {"key1": "val1"}))
 
358
        self.assertEqual(
 
359
            "/,key1=val1,key2=val2",
346
360
            join_segment_parameters("/,key1=val1", {"key2": "val2"}))
347
361
        self.assertRaises(TypeError,
348
 
            join_segment_parameters, "/,key1=val1", {"foo": 42})
 
362
                          join_segment_parameters, "/,key1=val1", {"foo": 42})
349
363
 
350
364
    def test_function_type(self):
351
365
        if sys.platform == 'win32':
352
366
            self.assertEqual(urlutils._win32_local_path_to_url,
353
 
                urlutils.local_path_to_url)
 
367
                             urlutils.local_path_to_url)
354
368
            self.assertEqual(urlutils._win32_local_path_from_url,
355
 
                urlutils.local_path_from_url)
 
369
                             urlutils.local_path_from_url)
356
370
        else:
357
371
            self.assertEqual(urlutils._posix_local_path_to_url,
358
 
                urlutils.local_path_to_url)
 
372
                             urlutils.local_path_to_url)
359
373
            self.assertEqual(urlutils._posix_local_path_from_url,
360
 
                urlutils.local_path_from_url)
 
374
                             urlutils.local_path_from_url)
361
375
 
362
376
    def test_posix_local_path_to_url(self):
363
377
        to_url = urlutils._posix_local_path_to_url
364
378
        self.assertEqual('file:///path/to/foo',
365
 
            to_url('/path/to/foo'))
 
379
                         to_url('/path/to/foo'))
366
380
 
367
381
        self.assertEqual('file:///path/to/foo%2Cbar',
368
 
            to_url('/path/to/foo,bar'))
 
382
                         to_url('/path/to/foo,bar'))
369
383
 
370
384
        try:
371
385
            result = to_url(u'/path/to/r\xe4ksm\xf6rg\xe5s')
378
392
    def test_posix_local_path_from_url(self):
379
393
        from_url = urlutils._posix_local_path_from_url
380
394
        self.assertEqual('/path/to/foo',
381
 
            from_url('file:///path/to/foo'))
 
395
                         from_url('file:///path/to/foo'))
382
396
        self.assertEqual('/path/to/foo',
383
 
            from_url('file:///path/to/foo,branch=foo'))
384
 
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
385
 
            from_url('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
386
 
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
387
 
            from_url('file:///path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
388
 
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
 
397
                         from_url('file:///path/to/foo,branch=foo'))
 
398
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
 
399
                         from_url('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
 
400
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
 
401
                         from_url('file:///path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
 
402
        self.assertEqual(
 
403
            u'/path/to/r\xe4ksm\xf6rg\xe5s',
389
404
            from_url('file://localhost/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
390
405
 
391
406
        self.assertRaises(urlutils.InvalidURL, from_url, '/path/to/foo')
396
411
    def test_win32_local_path_to_url(self):
397
412
        to_url = urlutils._win32_local_path_to_url
398
413
        self.assertEqual('file:///C:/path/to/foo',
399
 
            to_url('C:/path/to/foo'))
 
414
                         to_url('C:/path/to/foo'))
400
415
        # BOGUS: on win32, ntpath.abspath will strip trailing
401
416
        #       whitespace, so this will always fail
402
417
        #       Though under linux, it fakes abspath support
404
419
        # self.assertEqual('file:///C:/path/to/foo%20',
405
420
        #     to_url('C:/path/to/foo '))
406
421
        self.assertEqual('file:///C:/path/to/f%20oo',
407
 
            to_url('C:/path/to/f oo'))
 
422
                         to_url('C:/path/to/f oo'))
408
423
 
409
424
        self.assertEqual('file:///', to_url('/'))
410
425
 
411
426
        self.assertEqual('file:///C:/path/to/foo%2Cbar',
412
 
            to_url('C:/path/to/foo,bar'))
 
427
                         to_url('C:/path/to/foo,bar'))
413
428
        try:
414
429
            result = to_url(u'd:/path/to/r\xe4ksm\xf6rg\xe5s')
415
430
        except UnicodeError:
416
431
            raise TestSkipped("local encoding cannot handle unicode")
417
432
 
418
 
        self.assertEqual('file:///D:/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
 
433
        self.assertEqual(
 
434
            'file:///D:/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
419
435
        self.assertIsInstance(result, str)
420
436
 
421
437
    def test_win32_unc_path_to_url(self):
422
438
        self.requireFeature(features.win32_feature)
423
439
        to_url = urlutils._win32_local_path_to_url
424
440
        self.assertEqual('file://HOST/path',
425
 
            to_url(r'\\HOST\path'))
 
441
                         to_url(r'\\HOST\path'))
426
442
        self.assertEqual('file://HOST/path',
427
 
            to_url('//HOST/path'))
 
443
                         to_url('//HOST/path'))
428
444
 
429
445
        try:
430
446
            result = to_url(u'//HOST/path/to/r\xe4ksm\xf6rg\xe5s')
431
447
        except UnicodeError:
432
448
            raise TestSkipped("local encoding cannot handle unicode")
433
449
 
434
 
        self.assertEqual('file://HOST/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
 
450
        self.assertEqual(
 
451
            'file://HOST/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
435
452
        self.assertFalse(isinstance(result, text_type))
436
453
 
437
454
    def test_win32_local_path_from_url(self):
438
455
        from_url = urlutils._win32_local_path_from_url
439
456
        self.assertEqual('C:/path/to/foo',
440
 
            from_url('file:///C|/path/to/foo'))
441
 
        self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
 
457
                         from_url('file:///C|/path/to/foo'))
 
458
        self.assertEqual(
 
459
            u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
442
460
            from_url('file:///d|/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
443
 
        self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
 
461
        self.assertEqual(
 
462
            u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
444
463
            from_url('file:///d:/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
445
464
        self.assertEqual('/', from_url('file:///'))
446
465
        self.assertEqual('C:/path/to/foo',
447
 
            from_url('file:///C|/path/to/foo,branch=foo'))
 
466
                         from_url('file:///C|/path/to/foo,branch=foo'))
448
467
 
449
468
        self.assertRaises(urlutils.InvalidURL, from_url, 'file:///C:')
450
469
        self.assertRaises(urlutils.InvalidURL, from_url, 'file:///c')
456
475
        from_url = urlutils._win32_local_path_from_url
457
476
        self.assertEqual('//HOST/path', from_url('file://HOST/path'))
458
477
        self.assertEqual('//HOST/path',
459
 
            from_url('file://HOST/path,branch=foo'))
 
478
                         from_url('file://HOST/path,branch=foo'))
460
479
        # despite IE allows 2, 4, 5 and 6 slashes in URL to another machine
461
480
        # we want to use only 2 slashes
462
481
        # Firefox understand only 5 slashes in URL, but it's ugly
463
482
        self.assertRaises(urlutils.InvalidURL, from_url, 'file:////HOST/path')
464
483
        self.assertRaises(urlutils.InvalidURL, from_url, 'file://///HOST/path')
465
 
        self.assertRaises(urlutils.InvalidURL, from_url, 'file://////HOST/path')
 
484
        self.assertRaises(urlutils.InvalidURL, from_url,
 
485
                          'file://////HOST/path')
466
486
        # check for file://C:/ instead of file:///C:/
467
487
        self.assertRaises(urlutils.InvalidURL, from_url, 'file://C:/path')
468
488
 
469
489
    def test_win32_extract_drive_letter(self):
470
490
        extract = urlutils._win32_extract_drive_letter
471
491
        self.assertEqual(('file:///C:', '/foo'), extract('file://', '/C:/foo'))
472
 
        self.assertEqual(('file:///d|', '/path'), extract('file://', '/d|/path'))
 
492
        self.assertEqual(('file:///d|', '/path'),
 
493
                         extract('file://', '/d|/path'))
473
494
        self.assertRaises(urlutils.InvalidURL, extract, 'file://', '/path')
474
495
        # Root drives without slash treated as invalid, see bug #841322
475
496
        self.assertEqual(('file:///C:', '/'), extract('file://', '/C:/'))
482
503
        # Test breezy.urlutils.split()
483
504
        split = urlutils.split
484
505
        if sys.platform == 'win32':
485
 
            self.assertRaises(urlutils.InvalidURL, split, 'file:///path/to/foo')
 
506
            self.assertRaises(urlutils.InvalidURL, split,
 
507
                              'file:///path/to/foo')
486
508
            self.assertEqual(('file:///C|/', 'foo'), split('file:///C|/foo'))
487
509
            self.assertEqual(('file:///C:/', ''), split('file:///C:/'))
488
510
        else:
489
511
            self.assertEqual(('file:///', 'foo'), split('file:///foo'))
490
512
            self.assertEqual(('file:///', ''), split('file:///'))
491
513
 
492
 
        self.assertEqual(('http://host/path/to', 'foo'), split('http://host/path/to/foo'))
493
 
        self.assertEqual(('http://host/path/to', 'foo'), split('http://host/path/to/foo/'))
494
 
        self.assertEqual(('http://host/path/to/foo', ''),
 
514
        self.assertEqual(('http://host/path/to', 'foo'),
 
515
                         split('http://host/path/to/foo'))
 
516
        self.assertEqual(('http://host/path/to', 'foo'),
 
517
                         split('http://host/path/to/foo/'))
 
518
        self.assertEqual(
 
519
            ('http://host/path/to/foo', ''),
495
520
            split('http://host/path/to/foo/', exclude_trailing_slash=False))
496
521
        self.assertEqual(('http://host/', 'path'), split('http://host/path'))
497
522
        self.assertEqual(('http://host/', ''), split('http://host/'))
498
523
        self.assertEqual(('http://host', ''), split('http://host'))
499
 
        self.assertEqual(('http:///nohost', 'path'), split('http:///nohost/path'))
 
524
        self.assertEqual(('http:///nohost', 'path'),
 
525
                         split('http:///nohost/path'))
500
526
 
501
527
        self.assertEqual(('random+scheme://user:pass@ahost:port/', 'path'),
502
 
            split('random+scheme://user:pass@ahost:port/path'))
 
528
                         split('random+scheme://user:pass@ahost:port/path'))
503
529
        self.assertEqual(('random+scheme://user:pass@ahost:port/', 'path'),
504
 
            split('random+scheme://user:pass@ahost:port/path/'))
 
530
                         split('random+scheme://user:pass@ahost:port/path/'))
505
531
        self.assertEqual(('random+scheme://user:pass@ahost:port/', ''),
506
 
            split('random+scheme://user:pass@ahost:port/'))
 
532
                         split('random+scheme://user:pass@ahost:port/'))
507
533
 
508
534
        # relative paths
509
535
        self.assertEqual(('path/to', 'foo'), split('path/to/foo'))
510
536
        self.assertEqual(('path/to', 'foo'), split('path/to/foo/'))
511
537
        self.assertEqual(('path/to/foo', ''),
512
 
            split('path/to/foo/', exclude_trailing_slash=False))
 
538
                         split('path/to/foo/', exclude_trailing_slash=False))
513
539
        self.assertEqual(('path/..', 'foo'), split('path/../foo'))
514
540
        self.assertEqual(('../path', 'foo'), split('../path/foo'))
515
541
 
517
543
        split_segment_parameters_raw = urlutils.split_segment_parameters_raw
518
544
        # Check relative references with absolute paths
519
545
        self.assertEqual(("/some/path", []),
520
 
            split_segment_parameters_raw("/some/path"))
 
546
                         split_segment_parameters_raw("/some/path"))
521
547
        self.assertEqual(("/some/path", ["tip"]),
522
 
            split_segment_parameters_raw("/some/path,tip"))
 
548
                         split_segment_parameters_raw("/some/path,tip"))
523
549
        self.assertEqual(("/some,dir/path", ["tip"]),
524
 
            split_segment_parameters_raw("/some,dir/path,tip"))
525
 
        self.assertEqual(("/somedir/path", ["heads%2Ftip"]),
 
550
                         split_segment_parameters_raw("/some,dir/path,tip"))
 
551
        self.assertEqual(
 
552
            ("/somedir/path", ["heads%2Ftip"]),
526
553
            split_segment_parameters_raw("/somedir/path,heads%2Ftip"))
527
 
        self.assertEqual(("/somedir/path", ["heads%2Ftip", "bar"]),
 
554
        self.assertEqual(
 
555
            ("/somedir/path", ["heads%2Ftip", "bar"]),
528
556
            split_segment_parameters_raw("/somedir/path,heads%2Ftip,bar"))
529
557
        # Check relative references with relative paths
530
558
        self.assertEqual(("", ["key1=val1"]),
531
 
            split_segment_parameters_raw(",key1=val1"))
 
559
                         split_segment_parameters_raw(",key1=val1"))
532
560
        self.assertEqual(("foo/", ["key1=val1"]),
533
 
            split_segment_parameters_raw("foo/,key1=val1"))
 
561
                         split_segment_parameters_raw("foo/,key1=val1"))
534
562
        self.assertEqual(("foo", ["key1=val1"]),
535
 
            split_segment_parameters_raw("foo,key1=val1"))
536
 
        self.assertEqual(("foo/base,la=bla/other/elements", []),
 
563
                         split_segment_parameters_raw("foo,key1=val1"))
 
564
        self.assertEqual(
 
565
            ("foo/base,la=bla/other/elements", []),
537
566
            split_segment_parameters_raw("foo/base,la=bla/other/elements"))
538
 
        self.assertEqual(("foo/base,la=bla/other/elements", ["a=b"]),
 
567
        self.assertEqual(
 
568
            ("foo/base,la=bla/other/elements", ["a=b"]),
539
569
            split_segment_parameters_raw("foo/base,la=bla/other/elements,a=b"))
540
570
        # TODO: Check full URLs as well as relative references
541
571
 
543
573
        split_segment_parameters = urlutils.split_segment_parameters
544
574
        # Check relative references with absolute paths
545
575
        self.assertEqual(("/some/path", {}),
546
 
            split_segment_parameters("/some/path"))
 
576
                         split_segment_parameters("/some/path"))
547
577
        self.assertEqual(("/some/path", {"branch": "tip"}),
548
 
            split_segment_parameters("/some/path,branch=tip"))
 
578
                         split_segment_parameters("/some/path,branch=tip"))
549
579
        self.assertEqual(("/some,dir/path", {"branch": "tip"}),
550
 
            split_segment_parameters("/some,dir/path,branch=tip"))
551
 
        self.assertEqual(("/somedir/path", {"ref": "heads%2Ftip"}),
 
580
                         split_segment_parameters("/some,dir/path,branch=tip"))
 
581
        self.assertEqual(
 
582
            ("/somedir/path", {"ref": "heads%2Ftip"}),
552
583
            split_segment_parameters("/somedir/path,ref=heads%2Ftip"))
553
584
        self.assertEqual(("/somedir/path",
554
 
            {"ref": "heads%2Ftip", "key1": "val1"}),
555
 
            split_segment_parameters(
556
 
                "/somedir/path,ref=heads%2Ftip,key1=val1"))
557
 
        self.assertEqual(("/somedir/path", {"ref": "heads%2F=tip"}),
 
585
                          {"ref": "heads%2Ftip", "key1": "val1"}),
 
586
                         split_segment_parameters(
 
587
            "/somedir/path,ref=heads%2Ftip,key1=val1"))
 
588
        self.assertEqual(
 
589
            ("/somedir/path", {"ref": "heads%2F=tip"}),
558
590
            split_segment_parameters("/somedir/path,ref=heads%2F=tip"))
559
591
        # Check relative references with relative paths
560
592
        self.assertEqual(("", {"key1": "val1"}),
561
 
            split_segment_parameters(",key1=val1"))
 
593
                         split_segment_parameters(",key1=val1"))
562
594
        self.assertEqual(("foo/", {"key1": "val1"}),
563
 
            split_segment_parameters("foo/,key1=val1"))
564
 
        self.assertEqual(("foo/base,key1=val1/other/elements", {}),
 
595
                         split_segment_parameters("foo/,key1=val1"))
 
596
        self.assertEqual(
 
597
            ("foo/base,key1=val1/other/elements", {}),
565
598
            split_segment_parameters("foo/base,key1=val1/other/elements"))
566
599
        self.assertEqual(("foo/base,key1=val1/other/elements",
567
 
            {"key2": "val2"}), split_segment_parameters(
568
 
                "foo/base,key1=val1/other/elements,key2=val2"))
 
600
                          {"key2": "val2"}), split_segment_parameters(
 
601
            "foo/base,key1=val1/other/elements,key2=val2"))
569
602
        # TODO: Check full URLs as well as relative references
570
603
 
571
604
    def test_win32_strip_local_trailing_slash(self):
599
632
        self.assertEqual('file://', sts('file://'))
600
633
 
601
634
        self.assertEqual('random+scheme://user:pass@ahost:port/path',
602
 
            sts('random+scheme://user:pass@ahost:port/path'))
 
635
                         sts('random+scheme://user:pass@ahost:port/path'))
603
636
        self.assertEqual('random+scheme://user:pass@ahost:port/path',
604
 
            sts('random+scheme://user:pass@ahost:port/path/'))
 
637
                         sts('random+scheme://user:pass@ahost:port/path/'))
605
638
        self.assertEqual('random+scheme://user:pass@ahost:port/',
606
 
            sts('random+scheme://user:pass@ahost:port/'))
 
639
                         sts('random+scheme://user:pass@ahost:port/'))
607
640
 
608
641
        # Make sure relative paths work too
609
642
        self.assertEqual('path/to/foo', sts('path/to/foo'))
666
699
 
667
700
        if not PY3:
668
701
            self.assertRaises(urlutils.InvalidURL, urlutils.unescape, u'\xe5')
669
 
        self.assertRaises((TypeError, urlutils.InvalidURL), urlutils.unescape, b'\xe5')
 
702
        self.assertRaises((TypeError, urlutils.InvalidURL),
 
703
                          urlutils.unescape, b'\xe5')
670
704
        if not PY3:
671
705
            self.assertRaises(urlutils.InvalidURL, urlutils.unescape, '%E5')
672
706
        else:
683
717
 
684
718
        test('a', 'http://host/', 'http://host/a')
685
719
        test('http://entirely/different', 'sftp://host/branch',
686
 
                    'http://entirely/different')
 
720
             'http://entirely/different')
687
721
        test('../person/feature', 'http://host/branch/mainline',
688
 
                    'http://host/branch/person/feature')
 
722
             'http://host/branch/person/feature')
689
723
        test('..', 'http://host/branch', 'http://host/')
690
 
        test('http://host2/branch', 'http://host1/branch', 'http://host2/branch')
 
724
        test('http://host2/branch', 'http://host1/branch',
 
725
             'http://host2/branch')
691
726
        test('.', 'http://host1/branch', 'http://host1/branch')
692
727
        test('../../../branch/2b', 'file:///home/jelmer/foo/bar/2b',
693
 
                    'file:///home/jelmer/branch/2b')
 
728
             'file:///home/jelmer/branch/2b')
694
729
        test('../../branch/2b', 'sftp://host/home/jelmer/bar/2b',
695
 
                    'sftp://host/home/jelmer/branch/2b')
 
730
             'sftp://host/home/jelmer/branch/2b')
696
731
        test('../../branch/feature/%2b', 'http://host/home/jelmer/bar/%2b',
697
 
                    'http://host/home/jelmer/branch/feature/%2b')
 
732
             'http://host/home/jelmer/branch/feature/%2b')
698
733
        test('../../branch/feature/2b', 'http://host/home/jelmer/bar/2b/',
699
 
                    'http://host/home/jelmer/branch/feature/2b')
 
734
             'http://host/home/jelmer/branch/feature/2b')
700
735
        # relative_url should preserve a trailing slash
701
736
        test('../../branch/feature/2b/', 'http://host/home/jelmer/bar/2b/',
702
 
                    'http://host/home/jelmer/branch/feature/2b/')
 
737
             'http://host/home/jelmer/branch/feature/2b/')
703
738
        test('../../branch/feature/2b/', 'http://host/home/jelmer/bar/2b',
704
 
                    'http://host/home/jelmer/branch/feature/2b/')
 
739
             'http://host/home/jelmer/branch/feature/2b/')
705
740
 
706
741
        # TODO: treat http://host as http://host/
707
742
        #       relative_url is typically called from a branch.base or
708
743
        #       transport.base which always ends with a /
709
 
        #test('a', 'http://host', 'http://host/a')
 
744
        # test('a', 'http://host', 'http://host/a')
710
745
        test('http://host/a', 'http://host', 'http://host/a')
711
 
        #test('.', 'http://host', 'http://host/')
 
746
        # test('.', 'http://host', 'http://host/')
712
747
        test('http://host/', 'http://host', 'http://host/')
713
 
        #test('.', 'http://host/', 'http://host')
 
748
        # test('.', 'http://host/', 'http://host')
714
749
        test('http://host', 'http://host/', 'http://host')
715
750
 
716
751
        # On Windows file:///C:/path/to and file:///D:/other/path
718
753
        if sys.platform == 'win32':
719
754
            # on the same drive
720
755
            test('../../other/path',
721
 
                'file:///C:/path/to', 'file:///C:/other/path')
722
 
            #~next two tests is failed, i.e. urlutils.relative_url expects
723
 
            #~to see normalized file URLs?
724
 
            #~test('../../other/path',
725
 
            #~    'file:///C:/path/to', 'file:///c:/other/path')
726
 
            #~test('../../other/path',
727
 
            #~    'file:///C:/path/to', 'file:///C|/other/path')
 
756
                 'file:///C:/path/to', 'file:///C:/other/path')
 
757
            # ~next two tests is failed, i.e. urlutils.relative_url expects
 
758
            # ~to see normalized file URLs?
 
759
            # ~test('../../other/path',
 
760
            # ~    'file:///C:/path/to', 'file:///c:/other/path')
 
761
            # ~test('../../other/path',
 
762
            # ~    'file:///C:/path/to', 'file:///C|/other/path')
728
763
 
729
764
            # check UNC paths too
730
765
            test('../../other/path',
731
 
                'file://HOST/base/path/to', 'file://HOST/base/other/path')
 
766
                 'file://HOST/base/path/to', 'file://HOST/base/other/path')
732
767
            # on different drives
733
768
            test('file:///D:/other/path',
734
 
                'file:///C:/path/to', 'file:///D:/other/path')
 
769
                 'file:///C:/path/to', 'file:///D:/other/path')
735
770
            # TODO: strictly saying in UNC path //HOST/base is full analog
736
771
            # of drive letter for hard disk, and this situation is also
737
772
            # should be exception from rules. [bialix 20071221]
813
848
 
814
849
    def test_rebase_success(self):
815
850
        self.assertEqual('../bar', urlutils.rebase_url('bar', 'http://baz/',
816
 
                         'http://baz/qux'))
817
 
        self.assertEqual('qux/bar', urlutils.rebase_url('bar',
818
 
                         'http://baz/qux', 'http://baz/'))
819
 
        self.assertEqual('.', urlutils.rebase_url('foo',
820
 
                         'http://bar/', 'http://bar/foo/'))
821
 
        self.assertEqual('qux/bar', urlutils.rebase_url('../bar',
822
 
                         'http://baz/qux/foo', 'http://baz/'))
 
851
                                                       'http://baz/qux'))
 
852
        self.assertEqual(
 
853
            'qux/bar',
 
854
            urlutils.rebase_url('bar', 'http://baz/qux', 'http://baz/'))
 
855
        self.assertEqual(
 
856
            '.', urlutils.rebase_url('foo', 'http://bar/', 'http://bar/foo/'))
 
857
        self.assertEqual(
 
858
            'qux/bar',
 
859
            urlutils.rebase_url('../bar', 'http://baz/qux/foo', 'http://baz/'))
823
860
 
824
861
    def test_determine_relative_path(self):
825
862
        self.assertEqual('../../baz/bar',
826
863
                         urlutils.determine_relative_path(
827
 
                         '/qux/quxx', '/baz/bar'))
 
864
                             '/qux/quxx', '/baz/bar'))
828
865
        self.assertEqual('..',
829
866
                         urlutils.determine_relative_path(
830
 
                         '/bar/baz', '/bar'))
 
867
                             '/bar/baz', '/bar'))
831
868
        self.assertEqual('baz',
832
869
                         urlutils.determine_relative_path(
833
 
                         '/bar', '/bar/baz'))
 
870
                             '/bar', '/bar/baz'))
834
871
        self.assertEqual('.', urlutils.determine_relative_path(
835
872
                         '/bar', '/bar'))
836
873
 
840
877
    def test_parse_simple(self):
841
878
        parsed = urlutils.parse_url('http://example.com:80/one')
842
879
        self.assertEqual(('http', None, None, 'example.com', 80, '/one'),
843
 
            parsed)
 
880
                         parsed)
844
881
 
845
882
    def test_ipv6(self):
846
883
        parsed = urlutils.parse_url('http://[1:2:3::40]/one')
847
884
        self.assertEqual(('http', None, None, '1:2:3::40', None, '/one'),
848
 
            parsed)
 
885
                         parsed)
849
886
 
850
887
    def test_ipv6_port(self):
851
888
        parsed = urlutils.parse_url('http://[1:2:3::40]:80/one')
852
889
        self.assertEqual(('http', None, None, '1:2:3::40', 80, '/one'),
853
 
            parsed)
 
890
                         parsed)
854
891
 
855
892
 
856
893
class TestURL(TestCase):
950
987
 
951
988
    def _with_posix_paths(self):
952
989
        self.overrideAttr(urlutils, "local_path_from_url",
953
 
            urlutils._posix_local_path_from_url)
 
990
                          urlutils._posix_local_path_from_url)
954
991
        self.overrideAttr(urlutils, "MIN_ABS_FILEURL_LENGTH", len("file:///"))
955
992
        self.overrideAttr(osutils, "normpath", osutils._posix_normpath)
956
993
        self.overrideAttr(osutils, "abspath", osutils._posix_abspath)
961
998
 
962
999
    def _with_win32_paths(self):
963
1000
        self.overrideAttr(urlutils, "local_path_from_url",
964
 
            urlutils._win32_local_path_from_url)
 
1001
                          urlutils._win32_local_path_from_url)
965
1002
        self.overrideAttr(urlutils, "MIN_ABS_FILEURL_LENGTH",
966
 
            urlutils.WIN32_MIN_ABS_FILEURL_LENGTH)
 
1003
                          urlutils.WIN32_MIN_ABS_FILEURL_LENGTH)
967
1004
        self.overrideAttr(osutils, "abspath", osutils._win32_abspath)
968
1005
        self.overrideAttr(osutils, "normpath", osutils._win32_normpath)
969
1006
        self.overrideAttr(osutils, "pathjoin", osutils._win32_pathjoin)
973
1010
    def test_same_url_posix(self):
974
1011
        self._with_posix_paths()
975
1012
        self.assertEqual("",
976
 
            urlutils.file_relpath("file:///a", "file:///a"))
977
 
        self.assertEqual("",
978
 
            urlutils.file_relpath("file:///a", "file:///a/"))
979
 
        self.assertEqual("",
980
 
            urlutils.file_relpath("file:///a/", "file:///a"))
 
1013
                         urlutils.file_relpath("file:///a", "file:///a"))
 
1014
        self.assertEqual("",
 
1015
                         urlutils.file_relpath("file:///a", "file:///a/"))
 
1016
        self.assertEqual("",
 
1017
                         urlutils.file_relpath("file:///a/", "file:///a"))
981
1018
 
982
1019
    def test_same_url_win32(self):
983
1020
        self._with_win32_paths()
984
1021
        self.assertEqual("",
985
 
            urlutils.file_relpath("file:///A:/", "file:///A:/"))
986
 
        self.assertEqual("",
987
 
            urlutils.file_relpath("file:///A|/", "file:///A:/"))
988
 
        self.assertEqual("",
989
 
            urlutils.file_relpath("file:///A:/b/", "file:///A:/b/"))
990
 
        self.assertEqual("",
991
 
            urlutils.file_relpath("file:///A:/b", "file:///A:/b/"))
992
 
        self.assertEqual("",
993
 
            urlutils.file_relpath("file:///A:/b/", "file:///A:/b"))
 
1022
                         urlutils.file_relpath("file:///A:/", "file:///A:/"))
 
1023
        self.assertEqual("",
 
1024
                         urlutils.file_relpath("file:///A|/", "file:///A:/"))
 
1025
        self.assertEqual(
 
1026
            "", urlutils.file_relpath("file:///A:/b/", "file:///A:/b/"))
 
1027
        self.assertEqual(
 
1028
            "", urlutils.file_relpath("file:///A:/b", "file:///A:/b/"))
 
1029
        self.assertEqual(
 
1030
            "", urlutils.file_relpath("file:///A:/b/", "file:///A:/b"))
994
1031
 
995
1032
    def test_child_posix(self):
996
1033
        self._with_posix_paths()
997
 
        self.assertEqual("b",
998
 
            urlutils.file_relpath("file:///a", "file:///a/b"))
999
 
        self.assertEqual("b",
1000
 
            urlutils.file_relpath("file:///a/", "file:///a/b"))
1001
 
        self.assertEqual("b/c",
1002
 
            urlutils.file_relpath("file:///a", "file:///a/b/c"))
 
1034
        self.assertEqual(
 
1035
            "b", urlutils.file_relpath("file:///a", "file:///a/b"))
 
1036
        self.assertEqual(
 
1037
            "b", urlutils.file_relpath("file:///a/", "file:///a/b"))
 
1038
        self.assertEqual(
 
1039
            "b/c", urlutils.file_relpath("file:///a", "file:///a/b/c"))
1003
1040
 
1004
1041
    def test_child_win32(self):
1005
1042
        self._with_win32_paths()
1006
 
        self.assertEqual("b",
1007
 
            urlutils.file_relpath("file:///A:/", "file:///A:/b"))
1008
 
        self.assertEqual("b",
1009
 
            urlutils.file_relpath("file:///A|/", "file:///A:/b"))
1010
 
        self.assertEqual("c",
1011
 
            urlutils.file_relpath("file:///A:/b", "file:///A:/b/c"))
1012
 
        self.assertEqual("c",
1013
 
            urlutils.file_relpath("file:///A:/b/", "file:///A:/b/c"))
1014
 
        self.assertEqual("c/d",
1015
 
            urlutils.file_relpath("file:///A:/b", "file:///A:/b/c/d"))
 
1043
        self.assertEqual(
 
1044
            "b", urlutils.file_relpath("file:///A:/", "file:///A:/b"))
 
1045
        self.assertEqual(
 
1046
            "b", urlutils.file_relpath("file:///A|/", "file:///A:/b"))
 
1047
        self.assertEqual(
 
1048
            "c", urlutils.file_relpath("file:///A:/b", "file:///A:/b/c"))
 
1049
        self.assertEqual(
 
1050
            "c", urlutils.file_relpath("file:///A:/b/", "file:///A:/b/c"))
 
1051
        self.assertEqual(
 
1052
            "c/d", urlutils.file_relpath("file:///A:/b", "file:///A:/b/c/d"))
1016
1053
 
1017
1054
    def test_sibling_posix(self):
1018
1055
        self._with_posix_paths()
1019
 
        self.assertRaises(PathNotChild,
 
1056
        self.assertRaises(
 
1057
            PathNotChild,
1020
1058
            urlutils.file_relpath, "file:///a/b", "file:///a/c")
1021
 
        self.assertRaises(PathNotChild,
 
1059
        self.assertRaises(
 
1060
            PathNotChild,
1022
1061
            urlutils.file_relpath, "file:///a/b/", "file:///a/c")
1023
 
        self.assertRaises(PathNotChild,
 
1062
        self.assertRaises(
 
1063
            PathNotChild,
1024
1064
            urlutils.file_relpath, "file:///a/b/", "file:///a/c/")
1025
1065
 
1026
1066
    def test_sibling_win32(self):
1027
1067
        self._with_win32_paths()
1028
 
        self.assertRaises(PathNotChild,
 
1068
        self.assertRaises(
 
1069
            PathNotChild,
1029
1070
            urlutils.file_relpath, "file:///A:/b", "file:///A:/c")
1030
 
        self.assertRaises(PathNotChild,
 
1071
        self.assertRaises(
 
1072
            PathNotChild,
1031
1073
            urlutils.file_relpath, "file:///A:/b/", "file:///A:/c")
1032
 
        self.assertRaises(PathNotChild,
 
1074
        self.assertRaises(
 
1075
            PathNotChild,
1033
1076
            urlutils.file_relpath, "file:///A:/b/", "file:///A:/c/")
1034
1077
 
1035
1078
    def test_parent_posix(self):
1036
1079
        self._with_posix_paths()
1037
1080
        self.assertRaises(PathNotChild,
1038
 
            urlutils.file_relpath, "file:///a/b", "file:///a")
 
1081
                          urlutils.file_relpath, "file:///a/b", "file:///a")
1039
1082
        self.assertRaises(PathNotChild,
1040
 
            urlutils.file_relpath, "file:///a/b", "file:///a/")
 
1083
                          urlutils.file_relpath, "file:///a/b", "file:///a/")
1041
1084
 
1042
1085
    def test_parent_win32(self):
1043
1086
        self._with_win32_paths()
1044
 
        self.assertRaises(PathNotChild,
 
1087
        self.assertRaises(
 
1088
            PathNotChild,
1045
1089
            urlutils.file_relpath, "file:///A:/b", "file:///A:/")
1046
 
        self.assertRaises(PathNotChild,
 
1090
        self.assertRaises(
 
1091
            PathNotChild,
1047
1092
            urlutils.file_relpath, "file:///A:/b/c", "file:///A:/b")
1048
1093
 
1049
1094