/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: Martin
  • Date: 2018-11-16 16:38:22 UTC
  • mto: This revision was merged to the branch mainline in revision 7172.
  • Revision ID: gzlist@googlemail.com-20181116163822-yg1h1cdng6w7w9kn
Make --profile-imports work on Python 3

Also tweak heading to line up correctly.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2012, 2015, 2016 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
19
19
import os
20
20
import sys
21
21
 
22
 
from bzrlib import osutils, urlutils, win32utils
23
 
from bzrlib.errors import InvalidURL, InvalidURLJoin, InvalidRebaseURLs
24
 
from bzrlib.tests import TestCaseInTempDir, TestCase, TestSkipped
 
22
from .. import osutils, urlutils, win32utils
 
23
from ..errors import (
 
24
    PathNotChild,
 
25
    )
 
26
from ..sixish import (
 
27
    text_type,
 
28
    PY3,
 
29
    )
 
30
from . import features, TestCaseInTempDir, TestCase, TestSkipped
25
31
 
26
32
 
27
33
class TestUrlToPath(TestCase):
28
34
 
29
35
    def test_basename(self):
30
 
        # bzrlib.urlutils.basename
31
 
        # Test bzrlib.urlutils.split()
 
36
        # breezy.urlutils.basename
 
37
        # Test breezy.urlutils.split()
32
38
        basename = urlutils.basename
33
39
        if sys.platform == 'win32':
34
 
            self.assertRaises(InvalidURL, basename, 'file:///path/to/foo')
 
40
            self.assertRaises(urlutils.InvalidURL, basename,
 
41
                    'file:///path/to/foo')
35
42
            self.assertEqual('foo', basename('file:///C|/foo'))
36
43
            self.assertEqual('foo', basename('file:///C:/foo'))
37
44
            self.assertEqual('', basename('file:///C:/'))
119
126
        eq('http://host/~bob%2525-._',
120
127
                normalize_url(u'http://host/%7Ebob%2525%2D%2E%5F'))
121
128
 
122
 
        # Normalize verifies URLs when they are not unicode
123
 
        # (indicating they did not come from the user)
124
 
        self.assertRaises(InvalidURL, normalize_url, 'http://host/\xb5')
125
 
        self.assertRaises(InvalidURL, normalize_url, 'http://host/ ')
 
129
        if not PY3:
 
130
            # On Python 2, normalize verifies URLs when they are not unicode
 
131
            # (indicating they did not come from the user)
 
132
            self.assertRaises(urlutils.InvalidURL, normalize_url,
 
133
                    b'http://host/\xb5')
 
134
            self.assertRaises(urlutils.InvalidURL, normalize_url, b'http://host/ ')
126
135
 
127
136
    def test_url_scheme_re(self):
128
137
        # Test paths that may be URLs
156
165
        # Weird stuff
157
166
        # Can't have slashes or colons in the scheme
158
167
        test_one('/path/to/://foo', None)
159
 
        test_one('path:path://foo', None)
 
168
        test_one('scheme:stuff://foo', ('scheme', 'stuff://foo'))
160
169
        # Must have more than one character for scheme
161
170
        test_one('C://foo', None)
162
171
        test_one('ab://foo', ('ab', 'foo'))
163
172
 
164
173
    def test_dirname(self):
165
 
        # Test bzrlib.urlutils.dirname()
 
174
        # Test breezy.urlutils.dirname()
166
175
        dirname = urlutils.dirname
167
176
        if sys.platform == 'win32':
168
 
            self.assertRaises(InvalidURL, dirname, 'file:///path/to/foo')
 
177
            self.assertRaises(urlutils.InvalidURL, dirname,
 
178
                'file:///path/to/foo')
169
179
            self.assertEqual('file:///C|/', dirname('file:///C|/foo'))
170
180
            self.assertEqual('file:///C|/', dirname('file:///C|/'))
171
181
        else:
195
205
            dirname('path/to/foo/', exclude_trailing_slash=False))
196
206
        self.assertEqual('path/..', dirname('path/../foo'))
197
207
        self.assertEqual('../path', dirname('../path/foo'))
 
208
    
 
209
    def test_is_url(self):
 
210
        self.assertTrue(urlutils.is_url('http://foo/bar'))
 
211
        self.assertTrue(urlutils.is_url('bzr+ssh://foo/bar'))
 
212
        self.assertTrue(urlutils.is_url('lp:foo/bar'))
 
213
        self.assertTrue(urlutils.is_url('file:///foo/bar'))
 
214
        self.assertFalse(urlutils.is_url(''))
 
215
        self.assertFalse(urlutils.is_url('foo'))
 
216
        self.assertFalse(urlutils.is_url('foo/bar'))
 
217
        self.assertFalse(urlutils.is_url('/foo'))
 
218
        self.assertFalse(urlutils.is_url('/foo/bar'))
 
219
        self.assertFalse(urlutils.is_url('C:/'))
 
220
        self.assertFalse(urlutils.is_url('C:/foo'))
 
221
        self.assertFalse(urlutils.is_url('C:/foo/bar'))
198
222
 
199
223
    def test_join(self):
200
224
        def test(expected, *args):
210
234
        test('http://foo/bar/baz', 'http://foo', 'bar/baz')
211
235
        test('http://foo/baz', 'http://foo', 'bar/../baz')
212
236
        test('http://foo/baz', 'http://foo/bar/', '../baz')
 
237
        test('lp:foo/bar', 'lp:foo', 'bar')
 
238
        test('lp:foo/bar/baz', 'lp:foo', 'bar/baz')
213
239
 
214
240
        # Absolute paths
215
241
        test('http://foo', 'http://foo') # abs url with nothing is preserved.
219
245
        test('http://bar/', 'http://foo', 'http://bar/')
220
246
        test('http://bar/a', 'http://foo', 'http://bar/a')
221
247
        test('http://bar/a/', 'http://foo', 'http://bar/a/')
 
248
        test('lp:bar', 'http://foo', 'lp:bar')
 
249
        test('lp:bar', 'lp:foo', 'lp:bar')
 
250
        test('file:///stuff', 'lp:foo', 'file:///stuff')
222
251
 
223
252
        # From a base path
224
253
        test('file:///foo', 'file:///', 'foo')
229
258
        # Invalid joinings
230
259
        # Cannot go above root
231
260
        # Implicitly at root:
232
 
        self.assertRaises(InvalidURLJoin, urlutils.join,
 
261
        self.assertRaises(urlutils.InvalidURLJoin, urlutils.join,
233
262
                'http://foo', '../baz')
234
 
        self.assertRaises(InvalidURLJoin, urlutils.join,
 
263
        self.assertRaises(urlutils.InvalidURLJoin, urlutils.join,
235
264
                'http://foo', '/..')
236
265
        # Joining from a path explicitly under the root.
237
 
        self.assertRaises(InvalidURLJoin, urlutils.join,
 
266
        self.assertRaises(urlutils.InvalidURLJoin, urlutils.join,
238
267
                'http://foo/a', '../../b')
239
268
 
240
269
    def test_joinpath(self):
266
295
 
267
296
        # Invalid joinings
268
297
        # Cannot go above root
269
 
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '../baz')
270
 
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '..')
271
 
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '/..')
 
298
        self.assertRaises(urlutils.InvalidURLJoin, urlutils.joinpath, '/',
 
299
                '../baz')
 
300
        self.assertRaises(urlutils.InvalidURLJoin, urlutils.joinpath, '/',
 
301
                '..')
 
302
        self.assertRaises(urlutils.InvalidURLJoin, urlutils.joinpath, '/',
 
303
                '/..')
 
304
 
 
305
    def test_join_segment_parameters_raw(self):
 
306
        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"))
 
311
        self.assertRaises(urlutils.InvalidURLJoin,
 
312
            join_segment_parameters_raw, "/somedir/path",
 
313
                "rawdata1,rawdata2,rawdata3")
 
314
        self.assertEqual("/somedir/path,bla,bar",
 
315
            join_segment_parameters_raw("/somedir/path", "bla", "bar"))
 
316
        self.assertEqual("/somedir,exist=some/path,bla,bar",
 
317
            join_segment_parameters_raw("/somedir,exist=some/path",
 
318
                "bla", "bar"))
 
319
        self.assertRaises(TypeError, join_segment_parameters_raw, 
 
320
            "/somepath", 42)
 
321
 
 
322
    def test_join_segment_parameters(self):
 
323
        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", 
 
327
            join_segment_parameters("/somedir/path", {"key1": "val1"}))
 
328
        self.assertRaises(urlutils.InvalidURLJoin,
 
329
            join_segment_parameters, "/somedir/path",
 
330
            {"branch": "brr,brr,brr"})
 
331
        self.assertRaises(urlutils.InvalidURLJoin,
 
332
            join_segment_parameters, "/somedir/path", {"key1=val1": "val2"})
 
333
        self.assertEqual("/somedir/path,key1=val1,key2=val2",
 
334
            join_segment_parameters("/somedir/path", {
 
335
                "key1": "val1", "key2": "val2"}))
 
336
        self.assertEqual("/somedir/path,key1=val1,key2=val2",
 
337
            join_segment_parameters("/somedir/path,key1=val1", {
 
338
                "key2": "val2"}))
 
339
        self.assertEqual("/somedir/path,key1=val2",
 
340
            join_segment_parameters("/somedir/path,key1=val1", {
 
341
                "key1": "val2"}))
 
342
        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",
 
346
            join_segment_parameters("/,key1=val1", {"key2": "val2"}))
 
347
        self.assertRaises(TypeError,
 
348
            join_segment_parameters, "/,key1=val1", {"foo": 42})
272
349
 
273
350
    def test_function_type(self):
274
351
        if sys.platform == 'win32':
275
 
            self.assertEqual(urlutils._win32_local_path_to_url, urlutils.local_path_to_url)
276
 
            self.assertEqual(urlutils._win32_local_path_from_url, urlutils.local_path_from_url)
 
352
            self.assertEqual(urlutils._win32_local_path_to_url,
 
353
                urlutils.local_path_to_url)
 
354
            self.assertEqual(urlutils._win32_local_path_from_url,
 
355
                urlutils.local_path_from_url)
277
356
        else:
278
 
            self.assertEqual(urlutils._posix_local_path_to_url, urlutils.local_path_to_url)
279
 
            self.assertEqual(urlutils._posix_local_path_from_url, urlutils.local_path_from_url)
 
357
            self.assertEqual(urlutils._posix_local_path_to_url,
 
358
                urlutils.local_path_to_url)
 
359
            self.assertEqual(urlutils._posix_local_path_from_url,
 
360
                urlutils.local_path_from_url)
280
361
 
281
362
    def test_posix_local_path_to_url(self):
282
363
        to_url = urlutils._posix_local_path_to_url
283
364
        self.assertEqual('file:///path/to/foo',
284
365
            to_url('/path/to/foo'))
285
366
 
 
367
        self.assertEqual('file:///path/to/foo%2Cbar',
 
368
            to_url('/path/to/foo,bar'))
 
369
 
286
370
        try:
287
371
            result = to_url(u'/path/to/r\xe4ksm\xf6rg\xe5s')
288
372
        except UnicodeError:
289
373
            raise TestSkipped("local encoding cannot handle unicode")
290
374
 
291
375
        self.assertEqual('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
292
 
        self.assertFalse(isinstance(result, unicode))
 
376
        self.assertTrue(isinstance(result, str))
293
377
 
294
378
    def test_posix_local_path_from_url(self):
295
379
        from_url = urlutils._posix_local_path_from_url
296
380
        self.assertEqual('/path/to/foo',
297
381
            from_url('file:///path/to/foo'))
 
382
        self.assertEqual('/path/to/foo',
 
383
            from_url('file:///path/to/foo,branch=foo'))
298
384
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
299
385
            from_url('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
300
386
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
302
388
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
303
389
            from_url('file://localhost/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
304
390
 
305
 
        self.assertRaises(InvalidURL, from_url, '/path/to/foo')
 
391
        self.assertRaises(urlutils.InvalidURL, from_url, '/path/to/foo')
306
392
        self.assertRaises(
307
 
            InvalidURL, from_url,
 
393
            urlutils.InvalidURL, from_url,
308
394
            'file://remotehost/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s')
309
395
 
310
396
    def test_win32_local_path_to_url(self):
322
408
 
323
409
        self.assertEqual('file:///', to_url('/'))
324
410
 
 
411
        self.assertEqual('file:///C:/path/to/foo%2Cbar',
 
412
            to_url('C:/path/to/foo,bar'))
325
413
        try:
326
414
            result = to_url(u'd:/path/to/r\xe4ksm\xf6rg\xe5s')
327
415
        except UnicodeError:
328
416
            raise TestSkipped("local encoding cannot handle unicode")
329
417
 
330
418
        self.assertEqual('file:///D:/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
331
 
        self.assertFalse(isinstance(result, unicode))
 
419
        self.assertIsInstance(result, str)
332
420
 
333
421
    def test_win32_unc_path_to_url(self):
 
422
        self.requireFeature(features.win32_feature)
334
423
        to_url = urlutils._win32_local_path_to_url
335
424
        self.assertEqual('file://HOST/path',
336
425
            to_url(r'\\HOST\path'))
343
432
            raise TestSkipped("local encoding cannot handle unicode")
344
433
 
345
434
        self.assertEqual('file://HOST/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
346
 
        self.assertFalse(isinstance(result, unicode))
 
435
        self.assertFalse(isinstance(result, text_type))
347
436
 
348
437
    def test_win32_local_path_from_url(self):
349
438
        from_url = urlutils._win32_local_path_from_url
354
443
        self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
355
444
            from_url('file:///d:/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
356
445
        self.assertEqual('/', from_url('file:///'))
 
446
        self.assertEqual('C:/path/to/foo',
 
447
            from_url('file:///C|/path/to/foo,branch=foo'))
357
448
 
358
 
        self.assertRaises(InvalidURL, from_url, '/path/to/foo')
 
449
        self.assertRaises(urlutils.InvalidURL, from_url, 'file:///C:')
 
450
        self.assertRaises(urlutils.InvalidURL, from_url, 'file:///c')
 
451
        self.assertRaises(urlutils.InvalidURL, from_url, '/path/to/foo')
359
452
        # Not a valid _win32 url, no drive letter
360
 
        self.assertRaises(InvalidURL, from_url, 'file:///path/to/foo')
 
453
        self.assertRaises(urlutils.InvalidURL, from_url, 'file:///path/to/foo')
361
454
 
362
455
    def test_win32_unc_path_from_url(self):
363
456
        from_url = urlutils._win32_local_path_from_url
364
457
        self.assertEqual('//HOST/path', from_url('file://HOST/path'))
 
458
        self.assertEqual('//HOST/path',
 
459
            from_url('file://HOST/path,branch=foo'))
365
460
        # despite IE allows 2, 4, 5 and 6 slashes in URL to another machine
366
461
        # we want to use only 2 slashes
367
462
        # Firefox understand only 5 slashes in URL, but it's ugly
368
 
        self.assertRaises(InvalidURL, from_url, 'file:////HOST/path')
369
 
        self.assertRaises(InvalidURL, from_url, 'file://///HOST/path')
370
 
        self.assertRaises(InvalidURL, from_url, 'file://////HOST/path')
 
463
        self.assertRaises(urlutils.InvalidURL, from_url, 'file:////HOST/path')
 
464
        self.assertRaises(urlutils.InvalidURL, from_url, 'file://///HOST/path')
 
465
        self.assertRaises(urlutils.InvalidURL, from_url, 'file://////HOST/path')
371
466
        # check for file://C:/ instead of file:///C:/
372
 
        self.assertRaises(InvalidURL, from_url, 'file://C:/path')
 
467
        self.assertRaises(urlutils.InvalidURL, from_url, 'file://C:/path')
373
468
 
374
469
    def test_win32_extract_drive_letter(self):
375
470
        extract = urlutils._win32_extract_drive_letter
376
471
        self.assertEqual(('file:///C:', '/foo'), extract('file://', '/C:/foo'))
377
472
        self.assertEqual(('file:///d|', '/path'), extract('file://', '/d|/path'))
378
 
        self.assertRaises(InvalidURL, extract, 'file://', '/path')
 
473
        self.assertRaises(urlutils.InvalidURL, extract, 'file://', '/path')
 
474
        # Root drives without slash treated as invalid, see bug #841322
 
475
        self.assertEqual(('file:///C:', '/'), extract('file://', '/C:/'))
 
476
        self.assertRaises(urlutils.InvalidURL, extract, 'file://', '/C:')
 
477
        # Invalid without drive separator or following forward slash
 
478
        self.assertRaises(urlutils.InvalidURL, extract, 'file://', '/C')
 
479
        self.assertRaises(urlutils.InvalidURL, extract, 'file://', '/C:ool')
379
480
 
380
481
    def test_split(self):
381
 
        # Test bzrlib.urlutils.split()
 
482
        # Test breezy.urlutils.split()
382
483
        split = urlutils.split
383
484
        if sys.platform == 'win32':
384
 
            self.assertRaises(InvalidURL, split, 'file:///path/to/foo')
 
485
            self.assertRaises(urlutils.InvalidURL, split, 'file:///path/to/foo')
385
486
            self.assertEqual(('file:///C|/', 'foo'), split('file:///C|/foo'))
386
487
            self.assertEqual(('file:///C:/', ''), split('file:///C:/'))
387
488
        else:
412
513
        self.assertEqual(('path/..', 'foo'), split('path/../foo'))
413
514
        self.assertEqual(('../path', 'foo'), split('../path/foo'))
414
515
 
 
516
    def test_split_segment_parameters_raw(self):
 
517
        split_segment_parameters_raw = urlutils.split_segment_parameters_raw
 
518
        # Check relative references with absolute paths
 
519
        self.assertEqual(("/some/path", []),
 
520
            split_segment_parameters_raw("/some/path"))
 
521
        self.assertEqual(("/some/path", ["tip"]),
 
522
            split_segment_parameters_raw("/some/path,tip"))
 
523
        self.assertEqual(("/some,dir/path", ["tip"]),
 
524
            split_segment_parameters_raw("/some,dir/path,tip"))
 
525
        self.assertEqual(("/somedir/path", ["heads%2Ftip"]),
 
526
            split_segment_parameters_raw("/somedir/path,heads%2Ftip"))
 
527
        self.assertEqual(("/somedir/path", ["heads%2Ftip", "bar"]),
 
528
            split_segment_parameters_raw("/somedir/path,heads%2Ftip,bar"))
 
529
        # Check relative references with relative paths
 
530
        self.assertEqual(("", ["key1=val1"]),
 
531
            split_segment_parameters_raw(",key1=val1"))
 
532
        self.assertEqual(("foo/", ["key1=val1"]),
 
533
            split_segment_parameters_raw("foo/,key1=val1"))
 
534
        self.assertEqual(("foo", ["key1=val1"]),
 
535
            split_segment_parameters_raw("foo,key1=val1"))
 
536
        self.assertEqual(("foo/base,la=bla/other/elements", []),
 
537
            split_segment_parameters_raw("foo/base,la=bla/other/elements"))
 
538
        self.assertEqual(("foo/base,la=bla/other/elements", ["a=b"]),
 
539
            split_segment_parameters_raw("foo/base,la=bla/other/elements,a=b"))
 
540
        # TODO: Check full URLs as well as relative references
 
541
 
 
542
    def test_split_segment_parameters(self):
 
543
        split_segment_parameters = urlutils.split_segment_parameters
 
544
        # Check relative references with absolute paths
 
545
        self.assertEqual(("/some/path", {}),
 
546
            split_segment_parameters("/some/path"))
 
547
        self.assertEqual(("/some/path", {"branch": "tip"}),
 
548
            split_segment_parameters("/some/path,branch=tip"))
 
549
        self.assertEqual(("/some,dir/path", {"branch": "tip"}),
 
550
            split_segment_parameters("/some,dir/path,branch=tip"))
 
551
        self.assertEqual(("/somedir/path", {"ref": "heads%2Ftip"}),
 
552
            split_segment_parameters("/somedir/path,ref=heads%2Ftip"))
 
553
        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"}),
 
558
            split_segment_parameters("/somedir/path,ref=heads%2F=tip"))
 
559
        # Check relative references with relative paths
 
560
        self.assertEqual(("", {"key1": "val1"}),
 
561
            split_segment_parameters(",key1=val1"))
 
562
        self.assertEqual(("foo/", {"key1": "val1"}),
 
563
            split_segment_parameters("foo/,key1=val1"))
 
564
        self.assertEqual(("foo/base,key1=val1/other/elements", {}),
 
565
            split_segment_parameters("foo/base,key1=val1/other/elements"))
 
566
        self.assertEqual(("foo/base,key1=val1/other/elements",
 
567
            {"key2": "val2"}), split_segment_parameters(
 
568
                "foo/base,key1=val1/other/elements,key2=val2"))
 
569
        # TODO: Check full URLs as well as relative references
 
570
 
415
571
    def test_win32_strip_local_trailing_slash(self):
416
572
        strip = urlutils._win32_strip_local_trailing_slash
417
573
        self.assertEqual('file://', strip('file://'))
459
615
        # Test that URLs are converted to nice unicode strings for display
460
616
        def test(expected, url, encoding='utf-8'):
461
617
            disp_url = urlutils.unescape_for_display(url, encoding=encoding)
462
 
            self.assertIsInstance(disp_url, unicode)
 
618
            self.assertIsInstance(disp_url, text_type)
463
619
            self.assertEqual(expected, disp_url)
464
620
 
465
621
        test('http://foo', 'http://foo')
499
655
    def test_escape(self):
500
656
        self.assertEqual('%25', urlutils.escape('%'))
501
657
        self.assertEqual('%C3%A5', urlutils.escape(u'\xe5'))
502
 
        self.assertFalse(isinstance(urlutils.escape(u'\xe5'), unicode))
 
658
        self.assertIsInstance(urlutils.escape(u'\xe5'), str)
503
659
 
504
660
    def test_escape_tildes(self):
505
661
        self.assertEqual('~foo', urlutils.escape('~foo'))
508
664
        self.assertEqual('%', urlutils.unescape('%25'))
509
665
        self.assertEqual(u'\xe5', urlutils.unescape('%C3%A5'))
510
666
 
511
 
        self.assertRaises(InvalidURL, urlutils.unescape, u'\xe5')
512
 
        self.assertRaises(InvalidURL, urlutils.unescape, '\xe5')
513
 
        self.assertRaises(InvalidURL, urlutils.unescape, '%E5')
 
667
        if not PY3:
 
668
            self.assertRaises(urlutils.InvalidURL, urlutils.unescape, u'\xe5')
 
669
        self.assertRaises((TypeError, urlutils.InvalidURL), urlutils.unescape, b'\xe5')
 
670
        if not PY3:
 
671
            self.assertRaises(urlutils.InvalidURL, urlutils.unescape, '%E5')
 
672
        else:
 
673
            self.assertEqual('\xe5', urlutils.unescape('%C3%A5'))
514
674
 
515
675
    def test_escape_unescape(self):
516
676
        self.assertEqual(u'\xe5', urlutils.unescape(urlutils.escape(u'\xe5')))
578
738
 
579
739
 
580
740
class TestCwdToURL(TestCaseInTempDir):
581
 
    """Test that local_path_to_url works base on the cwd"""
 
741
    """Test that local_path_to_url works based on the cwd"""
582
742
 
583
743
    def test_dot(self):
584
744
        # This test will fail if getcwd is not ascii
589
749
        self.assertEndsWith(url, '/mytest')
590
750
 
591
751
    def test_non_ascii(self):
592
 
        if win32utils.winver == 'Windows 98':
593
 
            raise TestSkipped('Windows 98 cannot handle unicode filenames')
594
 
 
595
752
        try:
596
753
            os.mkdir(u'dod\xe9')
597
754
        except UnicodeError:
637
794
        self.assertEqual('/foo', result)
638
795
 
639
796
    def test_different_ports(self):
640
 
        e = self.assertRaises(InvalidRebaseURLs, urlutils.rebase_url,
 
797
        e = self.assertRaises(urlutils.InvalidRebaseURLs, urlutils.rebase_url,
641
798
                              'foo', 'http://bar:80', 'http://bar:81')
642
799
        self.assertEqual(str(e), "URLs differ by more than path:"
643
800
                         " 'http://bar:80' and 'http://bar:81'")
644
801
 
645
802
    def test_different_hosts(self):
646
 
        e = self.assertRaises(InvalidRebaseURLs, urlutils.rebase_url,
 
803
        e = self.assertRaises(urlutils.InvalidRebaseURLs, urlutils.rebase_url,
647
804
                              'foo', 'http://bar', 'http://baz')
648
805
        self.assertEqual(str(e), "URLs differ by more than path: 'http://bar'"
649
806
                         " and 'http://baz'")
650
807
 
651
808
    def test_different_protocol(self):
652
 
        e = self.assertRaises(InvalidRebaseURLs, urlutils.rebase_url,
 
809
        e = self.assertRaises(urlutils.InvalidRebaseURLs, urlutils.rebase_url,
653
810
                              'foo', 'http://bar', 'ftp://bar')
654
811
        self.assertEqual(str(e), "URLs differ by more than path: 'http://bar'"
655
812
                         " and 'ftp://bar'")
680
837
 
681
838
class TestParseURL(TestCase):
682
839
 
683
 
    def test_parse_url(self):
684
 
        self.assertEqual(urlutils.parse_url('http://example.com:80/one'),
685
 
            ('http', None, None, 'example.com', 80, '/one'))
686
 
        self.assertEqual(urlutils.parse_url('http://[1:2:3::40]/one'),
687
 
                ('http', None, None, '1:2:3::40', None, '/one'))
688
 
        self.assertEqual(urlutils.parse_url('http://[1:2:3::40]:80/one'),
689
 
                ('http', None, None, '1:2:3::40', 80, '/one'))
 
840
    def test_parse_simple(self):
 
841
        parsed = urlutils.parse_url('http://example.com:80/one')
 
842
        self.assertEqual(('http', None, None, 'example.com', 80, '/one'),
 
843
            parsed)
 
844
 
 
845
    def test_ipv6(self):
 
846
        parsed = urlutils.parse_url('http://[1:2:3::40]/one')
 
847
        self.assertEqual(('http', None, None, '1:2:3::40', None, '/one'),
 
848
            parsed)
 
849
 
 
850
    def test_ipv6_port(self):
 
851
        parsed = urlutils.parse_url('http://[1:2:3::40]:80/one')
 
852
        self.assertEqual(('http', None, None, '1:2:3::40', 80, '/one'),
 
853
            parsed)
 
854
 
 
855
 
 
856
class TestURL(TestCase):
 
857
 
 
858
    def test_parse_simple(self):
 
859
        parsed = urlutils.URL.from_string('http://example.com:80/one')
 
860
        self.assertEqual('http', parsed.scheme)
 
861
        self.assertIs(None, parsed.user)
 
862
        self.assertIs(None, parsed.password)
 
863
        self.assertEqual('example.com', parsed.host)
 
864
        self.assertEqual(80, parsed.port)
 
865
        self.assertEqual('/one', parsed.path)
 
866
 
 
867
    def test_ipv6(self):
 
868
        parsed = urlutils.URL.from_string('http://[1:2:3::40]/one')
 
869
        self.assertEqual('http', parsed.scheme)
 
870
        self.assertIs(None, parsed.port)
 
871
        self.assertIs(None, parsed.user)
 
872
        self.assertIs(None, parsed.password)
 
873
        self.assertEqual('1:2:3::40', parsed.host)
 
874
        self.assertEqual('/one', parsed.path)
 
875
 
 
876
    def test_ipv6_port(self):
 
877
        parsed = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
 
878
        self.assertEqual('http', parsed.scheme)
 
879
        self.assertEqual('1:2:3::40', parsed.host)
 
880
        self.assertIs(None, parsed.user)
 
881
        self.assertIs(None, parsed.password)
 
882
        self.assertEqual(80, parsed.port)
 
883
        self.assertEqual('/one', parsed.path)
 
884
 
 
885
    def test_quoted(self):
 
886
        parsed = urlutils.URL.from_string(
 
887
            'http://ro%62ey:h%40t@ex%41mple.com:2222/path')
 
888
        self.assertEqual(parsed.quoted_host, 'ex%41mple.com')
 
889
        self.assertEqual(parsed.host, 'exAmple.com')
 
890
        self.assertEqual(parsed.port, 2222)
 
891
        self.assertEqual(parsed.quoted_user, 'ro%62ey')
 
892
        self.assertEqual(parsed.user, 'robey')
 
893
        self.assertEqual(parsed.quoted_password, 'h%40t')
 
894
        self.assertEqual(parsed.password, 'h@t')
 
895
        self.assertEqual(parsed.path, '/path')
 
896
 
 
897
    def test_eq(self):
 
898
        parsed1 = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
 
899
        parsed2 = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
 
900
        self.assertEqual(parsed1, parsed2)
 
901
        self.assertEqual(parsed1, parsed1)
 
902
        parsed2.path = '/two'
 
903
        self.assertNotEqual(parsed1, parsed2)
 
904
 
 
905
    def test_repr(self):
 
906
        parsed = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
 
907
        self.assertEqual(
 
908
            "<URL('http', None, None, '1:2:3::40', 80, '/one')>",
 
909
            repr(parsed))
 
910
 
 
911
    def test_str(self):
 
912
        parsed = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
 
913
        self.assertEqual('http://[1:2:3::40]:80/one', str(parsed))
 
914
 
 
915
    def test__combine_paths(self):
 
916
        combine = urlutils.URL._combine_paths
 
917
        self.assertEqual('/home/sarah/project/foo',
 
918
                         combine('/home/sarah', 'project/foo'))
 
919
        self.assertEqual('/etc',
 
920
                         combine('/home/sarah', '../../etc'))
 
921
        self.assertEqual('/etc',
 
922
                         combine('/home/sarah', '../../../etc'))
 
923
        self.assertEqual('/etc',
 
924
                         combine('/home/sarah', '/etc'))
 
925
 
 
926
    def test_clone(self):
 
927
        url = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
 
928
        url1 = url.clone("two")
 
929
        self.assertEqual("/one/two", url1.path)
 
930
        url2 = url.clone("/two")
 
931
        self.assertEqual("/two", url2.path)
 
932
        url3 = url.clone()
 
933
        self.assertIsNot(url, url3)
 
934
        self.assertEqual(url, url3)
 
935
 
 
936
    def test_parse_empty_port(self):
 
937
        parsed = urlutils.URL.from_string('http://example.com:/one')
 
938
        self.assertEqual('http', parsed.scheme)
 
939
        self.assertIs(None, parsed.user)
 
940
        self.assertIs(None, parsed.password)
 
941
        self.assertEqual('example.com', parsed.host)
 
942
        self.assertIs(None, parsed.port)
 
943
        self.assertEqual('/one', parsed.path)
 
944
 
 
945
 
 
946
class TestFileRelpath(TestCase):
 
947
 
 
948
    # GZ 2011-11-18: A way to override all path handling functions to one
 
949
    #                platform or another for testing would be nice.
 
950
 
 
951
    def _with_posix_paths(self):
 
952
        self.overrideAttr(urlutils, "local_path_from_url",
 
953
            urlutils._posix_local_path_from_url)
 
954
        self.overrideAttr(urlutils, "MIN_ABS_FILEURL_LENGTH", len("file:///"))
 
955
        self.overrideAttr(osutils, "normpath", osutils._posix_normpath)
 
956
        self.overrideAttr(osutils, "abspath", osutils._posix_abspath)
 
957
        self.overrideAttr(osutils, "normpath", osutils._posix_normpath)
 
958
        self.overrideAttr(osutils, "pathjoin", osutils.posixpath.join)
 
959
        self.overrideAttr(osutils, "split", osutils.posixpath.split)
 
960
        self.overrideAttr(osutils, "MIN_ABS_PATHLENGTH", 1)
 
961
 
 
962
    def _with_win32_paths(self):
 
963
        self.overrideAttr(urlutils, "local_path_from_url",
 
964
            urlutils._win32_local_path_from_url)
 
965
        self.overrideAttr(urlutils, "MIN_ABS_FILEURL_LENGTH",
 
966
            urlutils.WIN32_MIN_ABS_FILEURL_LENGTH)
 
967
        self.overrideAttr(osutils, "abspath", osutils._win32_abspath)
 
968
        self.overrideAttr(osutils, "normpath", osutils._win32_normpath)
 
969
        self.overrideAttr(osutils, "pathjoin", osutils._win32_pathjoin)
 
970
        self.overrideAttr(osutils, "split", osutils.ntpath.split)
 
971
        self.overrideAttr(osutils, "MIN_ABS_PATHLENGTH", 3)
 
972
 
 
973
    def test_same_url_posix(self):
 
974
        self._with_posix_paths()
 
975
        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"))
 
981
 
 
982
    def test_same_url_win32(self):
 
983
        self._with_win32_paths()
 
984
        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"))
 
994
 
 
995
    def test_child_posix(self):
 
996
        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"))
 
1003
 
 
1004
    def test_child_win32(self):
 
1005
        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"))
 
1016
 
 
1017
    def test_sibling_posix(self):
 
1018
        self._with_posix_paths()
 
1019
        self.assertRaises(PathNotChild,
 
1020
            urlutils.file_relpath, "file:///a/b", "file:///a/c")
 
1021
        self.assertRaises(PathNotChild,
 
1022
            urlutils.file_relpath, "file:///a/b/", "file:///a/c")
 
1023
        self.assertRaises(PathNotChild,
 
1024
            urlutils.file_relpath, "file:///a/b/", "file:///a/c/")
 
1025
 
 
1026
    def test_sibling_win32(self):
 
1027
        self._with_win32_paths()
 
1028
        self.assertRaises(PathNotChild,
 
1029
            urlutils.file_relpath, "file:///A:/b", "file:///A:/c")
 
1030
        self.assertRaises(PathNotChild,
 
1031
            urlutils.file_relpath, "file:///A:/b/", "file:///A:/c")
 
1032
        self.assertRaises(PathNotChild,
 
1033
            urlutils.file_relpath, "file:///A:/b/", "file:///A:/c/")
 
1034
 
 
1035
    def test_parent_posix(self):
 
1036
        self._with_posix_paths()
 
1037
        self.assertRaises(PathNotChild,
 
1038
            urlutils.file_relpath, "file:///a/b", "file:///a")
 
1039
        self.assertRaises(PathNotChild,
 
1040
            urlutils.file_relpath, "file:///a/b", "file:///a/")
 
1041
 
 
1042
    def test_parent_win32(self):
 
1043
        self._with_win32_paths()
 
1044
        self.assertRaises(PathNotChild,
 
1045
            urlutils.file_relpath, "file:///A:/b", "file:///A:/")
 
1046
        self.assertRaises(PathNotChild,
 
1047
            urlutils.file_relpath, "file:///A:/b/c", "file:///A:/b")
 
1048
 
 
1049
 
 
1050
class QuoteTests(TestCase):
 
1051
 
 
1052
    def test_quote(self):
 
1053
        self.assertEqual('abc%20def', urlutils.quote('abc def'))
 
1054
        self.assertEqual('abc%2Fdef', urlutils.quote('abc/def', safe=''))
 
1055
        self.assertEqual('abc/def', urlutils.quote('abc/def', safe='/'))
 
1056
 
 
1057
    def test_quote_tildes(self):
 
1058
        self.assertEqual('%7Efoo', urlutils.quote('~foo'))
 
1059
        self.assertEqual('~foo', urlutils.quote('~foo', safe='/~'))
 
1060
 
 
1061
    def test_unquote(self):
 
1062
        self.assertEqual('%', urlutils.unquote('%25'))
 
1063
        if PY3:
 
1064
            self.assertEqual('\xe5', urlutils.unquote('%C3%A5'))
 
1065
        else:
 
1066
            self.assertEqual('\xc3\xa5', urlutils.unquote('%C3%A5'))
 
1067
        self.assertEqual(u"\xe5", urlutils.unquote(u'\xe5'))
 
1068
 
 
1069
    def test_unquote_to_bytes(self):
 
1070
        self.assertEqual(b'%', urlutils.unquote_to_bytes('%25'))
 
1071
        self.assertEqual(b'\xc3\xa5', urlutils.unquote_to_bytes('%C3%A5'))