~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_urlutils.py

  • Committer: Vincent Ladeuil
  • Date: 2017-01-17 13:48:10 UTC
  • mfrom: (6615.3.6 merges)
  • mto: This revision was merged to the branch mainline in revision 6620.
  • Revision ID: v.ladeuil+lp@free.fr-20170117134810-j9p3lidfy6pfyfsc
Merge 2.7, resolving conflicts

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
20
20
import sys
21
21
 
22
22
from bzrlib import osutils, urlutils, win32utils
23
 
from bzrlib.errors import InvalidURL, InvalidURLJoin, InvalidRebaseURLs
24
 
from bzrlib.tests import TestCaseInTempDir, TestCase, TestSkipped
 
23
from bzrlib.errors import (
 
24
    InvalidURL,
 
25
    InvalidURLJoin,
 
26
    InvalidRebaseURLs,
 
27
    PathNotChild,
 
28
    )
 
29
from bzrlib.tests import features, TestCaseInTempDir, TestCase, TestSkipped
25
30
 
26
31
 
27
32
class TestUrlToPath(TestCase):
291
296
 
292
297
    def test_join_segment_parameters_raw(self):
293
298
        join_segment_parameters_raw = urlutils.join_segment_parameters_raw
294
 
        self.assertEquals("/somedir/path", 
 
299
        self.assertEqual("/somedir/path", 
295
300
            join_segment_parameters_raw("/somedir/path"))
296
 
        self.assertEquals("/somedir/path,rawdata", 
 
301
        self.assertEqual("/somedir/path,rawdata", 
297
302
            join_segment_parameters_raw("/somedir/path", "rawdata"))
298
303
        self.assertRaises(InvalidURLJoin,
299
304
            join_segment_parameters_raw, "/somedir/path",
300
305
                "rawdata1,rawdata2,rawdata3")
301
 
        self.assertEquals("/somedir/path,bla,bar",
 
306
        self.assertEqual("/somedir/path,bla,bar",
302
307
            join_segment_parameters_raw("/somedir/path", "bla", "bar"))
303
 
        self.assertEquals("/somedir,exist=some/path,bla,bar",
 
308
        self.assertEqual("/somedir,exist=some/path,bla,bar",
304
309
            join_segment_parameters_raw("/somedir,exist=some/path",
305
310
                "bla", "bar"))
306
311
        self.assertRaises(TypeError, join_segment_parameters_raw, 
308
313
 
309
314
    def test_join_segment_parameters(self):
310
315
        join_segment_parameters = urlutils.join_segment_parameters
311
 
        self.assertEquals("/somedir/path", 
 
316
        self.assertEqual("/somedir/path", 
312
317
            join_segment_parameters("/somedir/path", {}))
313
 
        self.assertEquals("/somedir/path,key1=val1", 
 
318
        self.assertEqual("/somedir/path,key1=val1", 
314
319
            join_segment_parameters("/somedir/path", {"key1": "val1"}))
315
320
        self.assertRaises(InvalidURLJoin,
316
321
            join_segment_parameters, "/somedir/path",
317
322
            {"branch": "brr,brr,brr"})
318
323
        self.assertRaises(InvalidURLJoin,
319
324
            join_segment_parameters, "/somedir/path", {"key1=val1": "val2"})
320
 
        self.assertEquals("/somedir/path,key1=val1,key2=val2",
 
325
        self.assertEqual("/somedir/path,key1=val1,key2=val2",
321
326
            join_segment_parameters("/somedir/path", {
322
327
                "key1": "val1", "key2": "val2"}))
323
 
        self.assertEquals("/somedir/path,key1=val1,key2=val2",
 
328
        self.assertEqual("/somedir/path,key1=val1,key2=val2",
324
329
            join_segment_parameters("/somedir/path,key1=val1", {
325
330
                "key2": "val2"}))
326
 
        self.assertEquals("/somedir/path,key1=val2",
 
331
        self.assertEqual("/somedir/path,key1=val2",
327
332
            join_segment_parameters("/somedir/path,key1=val1", {
328
333
                "key1": "val2"}))
329
 
        self.assertEquals("/somedir,exist=some/path,key1=val1",
 
334
        self.assertEqual("/somedir,exist=some/path,key1=val1",
330
335
            join_segment_parameters("/somedir,exist=some/path",
331
336
                {"key1": "val1"}))
332
 
        self.assertEquals("/,key1=val1,key2=val2",
 
337
        self.assertEqual("/,key1=val1,key2=val2",
333
338
            join_segment_parameters("/,key1=val1", {"key2": "val2"}))
334
339
        self.assertRaises(TypeError,
335
340
            join_segment_parameters, "/,key1=val1", {"foo": 42})
336
341
 
337
342
    def test_function_type(self):
338
343
        if sys.platform == 'win32':
339
 
            self.assertEqual(urlutils._win32_local_path_to_url, urlutils.local_path_to_url)
340
 
            self.assertEqual(urlutils._win32_local_path_from_url, urlutils.local_path_from_url)
 
344
            self.assertEqual(urlutils._win32_local_path_to_url,
 
345
                urlutils.local_path_to_url)
 
346
            self.assertEqual(urlutils._win32_local_path_from_url,
 
347
                urlutils.local_path_from_url)
341
348
        else:
342
 
            self.assertEqual(urlutils._posix_local_path_to_url, urlutils.local_path_to_url)
343
 
            self.assertEqual(urlutils._posix_local_path_from_url, urlutils.local_path_from_url)
 
349
            self.assertEqual(urlutils._posix_local_path_to_url,
 
350
                urlutils.local_path_to_url)
 
351
            self.assertEqual(urlutils._posix_local_path_from_url,
 
352
                urlutils.local_path_from_url)
344
353
 
345
354
    def test_posix_local_path_to_url(self):
346
355
        to_url = urlutils._posix_local_path_to_url
347
356
        self.assertEqual('file:///path/to/foo',
348
357
            to_url('/path/to/foo'))
349
358
 
 
359
        self.assertEqual('file:///path/to/foo%2Cbar',
 
360
            to_url('/path/to/foo,bar'))
 
361
 
350
362
        try:
351
363
            result = to_url(u'/path/to/r\xe4ksm\xf6rg\xe5s')
352
364
        except UnicodeError:
359
371
        from_url = urlutils._posix_local_path_from_url
360
372
        self.assertEqual('/path/to/foo',
361
373
            from_url('file:///path/to/foo'))
 
374
        self.assertEqual('/path/to/foo',
 
375
            from_url('file:///path/to/foo,branch=foo'))
362
376
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
363
377
            from_url('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
364
378
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
386
400
 
387
401
        self.assertEqual('file:///', to_url('/'))
388
402
 
 
403
        self.assertEqual('file:///C:/path/to/foo%2Cbar',
 
404
            to_url('C:/path/to/foo,bar'))
389
405
        try:
390
406
            result = to_url(u'd:/path/to/r\xe4ksm\xf6rg\xe5s')
391
407
        except UnicodeError:
395
411
        self.assertFalse(isinstance(result, unicode))
396
412
 
397
413
    def test_win32_unc_path_to_url(self):
 
414
        self.requireFeature(features.win32_feature)
398
415
        to_url = urlutils._win32_local_path_to_url
399
416
        self.assertEqual('file://HOST/path',
400
417
            to_url(r'\\HOST\path'))
418
435
        self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
419
436
            from_url('file:///d:/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
420
437
        self.assertEqual('/', from_url('file:///'))
 
438
        self.assertEqual('C:/path/to/foo',
 
439
            from_url('file:///C|/path/to/foo,branch=foo'))
421
440
 
 
441
        self.assertRaises(InvalidURL, from_url, 'file:///C:')
 
442
        self.assertRaises(InvalidURL, from_url, 'file:///c')
422
443
        self.assertRaises(InvalidURL, from_url, '/path/to/foo')
423
444
        # Not a valid _win32 url, no drive letter
424
445
        self.assertRaises(InvalidURL, from_url, 'file:///path/to/foo')
426
447
    def test_win32_unc_path_from_url(self):
427
448
        from_url = urlutils._win32_local_path_from_url
428
449
        self.assertEqual('//HOST/path', from_url('file://HOST/path'))
 
450
        self.assertEqual('//HOST/path',
 
451
            from_url('file://HOST/path,branch=foo'))
429
452
        # despite IE allows 2, 4, 5 and 6 slashes in URL to another machine
430
453
        # we want to use only 2 slashes
431
454
        # Firefox understand only 5 slashes in URL, but it's ugly
440
463
        self.assertEqual(('file:///C:', '/foo'), extract('file://', '/C:/foo'))
441
464
        self.assertEqual(('file:///d|', '/path'), extract('file://', '/d|/path'))
442
465
        self.assertRaises(InvalidURL, extract, 'file://', '/path')
 
466
        # Root drives without slash treated as invalid, see bug #841322
 
467
        self.assertEqual(('file:///C:', '/'), extract('file://', '/C:/'))
 
468
        self.assertRaises(InvalidURL, extract, 'file://', '/C:')
 
469
        # Invalid without drive separator or following forward slash
 
470
        self.assertRaises(InvalidURL, extract, 'file://', '/C')
 
471
        self.assertRaises(InvalidURL, extract, 'file://', '/C:ool')
443
472
 
444
473
    def test_split(self):
445
474
        # Test bzrlib.urlutils.split()
478
507
 
479
508
    def test_split_segment_parameters_raw(self):
480
509
        split_segment_parameters_raw = urlutils.split_segment_parameters_raw
481
 
        self.assertEquals(("/some/path", []),
 
510
        # Check relative references with absolute paths
 
511
        self.assertEqual(("/some/path", []),
482
512
            split_segment_parameters_raw("/some/path"))
483
 
        self.assertEquals(("/some/path", ["tip"]),
 
513
        self.assertEqual(("/some/path", ["tip"]),
484
514
            split_segment_parameters_raw("/some/path,tip"))
485
 
        self.assertEquals(("/some,dir/path", ["tip"]),
 
515
        self.assertEqual(("/some,dir/path", ["tip"]),
486
516
            split_segment_parameters_raw("/some,dir/path,tip"))
487
 
        self.assertEquals(("/somedir/path", ["heads%2Ftip"]),
 
517
        self.assertEqual(("/somedir/path", ["heads%2Ftip"]),
488
518
            split_segment_parameters_raw("/somedir/path,heads%2Ftip"))
489
 
        self.assertEquals(("/somedir/path", ["heads%2Ftip", "bar"]),
 
519
        self.assertEqual(("/somedir/path", ["heads%2Ftip", "bar"]),
490
520
            split_segment_parameters_raw("/somedir/path,heads%2Ftip,bar"))
491
 
        self.assertEquals(("/", ["key1=val1"]),
 
521
        # Check relative references with relative paths
 
522
        self.assertEqual(("", ["key1=val1"]),
492
523
            split_segment_parameters_raw(",key1=val1"))
493
 
        self.assertEquals(("foo/", ["key1=val1"]),
 
524
        self.assertEqual(("foo/", ["key1=val1"]),
494
525
            split_segment_parameters_raw("foo/,key1=val1"))
495
 
        self.assertEquals(("foo/base,la=bla/other/elements", []),
 
526
        self.assertEqual(("foo", ["key1=val1"]),
 
527
            split_segment_parameters_raw("foo,key1=val1"))
 
528
        self.assertEqual(("foo/base,la=bla/other/elements", []),
496
529
            split_segment_parameters_raw("foo/base,la=bla/other/elements"))
497
 
        self.assertEquals(("foo/base,la=bla/other/elements", ["a=b"]),
 
530
        self.assertEqual(("foo/base,la=bla/other/elements", ["a=b"]),
498
531
            split_segment_parameters_raw("foo/base,la=bla/other/elements,a=b"))
 
532
        # TODO: Check full URLs as well as relative references
499
533
 
500
534
    def test_split_segment_parameters(self):
501
535
        split_segment_parameters = urlutils.split_segment_parameters
502
 
        self.assertEquals(("/some/path", {}),
 
536
        # Check relative references with absolute paths
 
537
        self.assertEqual(("/some/path", {}),
503
538
            split_segment_parameters("/some/path"))
504
 
        self.assertEquals(("/some/path", {"branch": "tip"}),
 
539
        self.assertEqual(("/some/path", {"branch": "tip"}),
505
540
            split_segment_parameters("/some/path,branch=tip"))
506
 
        self.assertEquals(("/some,dir/path", {"branch": "tip"}),
 
541
        self.assertEqual(("/some,dir/path", {"branch": "tip"}),
507
542
            split_segment_parameters("/some,dir/path,branch=tip"))
508
 
        self.assertEquals(("/somedir/path", {"ref": "heads%2Ftip"}),
 
543
        self.assertEqual(("/somedir/path", {"ref": "heads%2Ftip"}),
509
544
            split_segment_parameters("/somedir/path,ref=heads%2Ftip"))
510
 
        self.assertEquals(("/somedir/path",
 
545
        self.assertEqual(("/somedir/path",
511
546
            {"ref": "heads%2Ftip", "key1": "val1"}),
512
547
            split_segment_parameters(
513
548
                "/somedir/path,ref=heads%2Ftip,key1=val1"))
514
 
        self.assertEquals(("/somedir/path", {"ref": "heads%2F=tip"}),
 
549
        self.assertEqual(("/somedir/path", {"ref": "heads%2F=tip"}),
515
550
            split_segment_parameters("/somedir/path,ref=heads%2F=tip"))
516
 
        self.assertEquals(("/", {"key1": "val1"}),
 
551
        # Check relative references with relative paths
 
552
        self.assertEqual(("", {"key1": "val1"}),
517
553
            split_segment_parameters(",key1=val1"))
518
 
        self.assertEquals(("foo/", {"key1": "val1"}),
 
554
        self.assertEqual(("foo/", {"key1": "val1"}),
519
555
            split_segment_parameters("foo/,key1=val1"))
520
 
        self.assertEquals(("foo/base,key1=val1/other/elements", {}),
 
556
        self.assertEqual(("foo/base,key1=val1/other/elements", {}),
521
557
            split_segment_parameters("foo/base,key1=val1/other/elements"))
522
 
        self.assertEquals(("foo/base,key1=val1/other/elements",
 
558
        self.assertEqual(("foo/base,key1=val1/other/elements",
523
559
            {"key2": "val2"}), split_segment_parameters(
524
560
                "foo/base,key1=val1/other/elements,key2=val2"))
 
561
        # TODO: Check full URLs as well as relative references
525
562
 
526
563
    def test_win32_strip_local_trailing_slash(self):
527
564
        strip = urlutils._win32_strip_local_trailing_slash
689
726
 
690
727
 
691
728
class TestCwdToURL(TestCaseInTempDir):
692
 
    """Test that local_path_to_url works base on the cwd"""
 
729
    """Test that local_path_to_url works based on the cwd"""
693
730
 
694
731
    def test_dot(self):
695
732
        # This test will fail if getcwd is not ascii
791
828
 
792
829
class TestParseURL(TestCase):
793
830
 
794
 
    def test_parse_url(self):
795
 
        self.assertEqual(urlutils.parse_url('http://example.com:80/one'),
796
 
            ('http', None, None, 'example.com', 80, '/one'))
797
 
        self.assertEqual(urlutils.parse_url('http://[1:2:3::40]/one'),
798
 
                ('http', None, None, '1:2:3::40', None, '/one'))
799
 
        self.assertEqual(urlutils.parse_url('http://[1:2:3::40]:80/one'),
800
 
                ('http', None, None, '1:2:3::40', 80, '/one'))
 
831
    def test_parse_simple(self):
 
832
        parsed = urlutils.parse_url('http://example.com:80/one')
 
833
        self.assertEqual(('http', None, None, 'example.com', 80, '/one'),
 
834
            parsed)
 
835
 
 
836
    def test_ipv6(self):
 
837
        parsed = urlutils.parse_url('http://[1:2:3::40]/one')
 
838
        self.assertEqual(('http', None, None, '1:2:3::40', None, '/one'),
 
839
            parsed)
 
840
 
 
841
    def test_ipv6_port(self):
 
842
        parsed = urlutils.parse_url('http://[1:2:3::40]:80/one')
 
843
        self.assertEqual(('http', None, None, '1:2:3::40', 80, '/one'),
 
844
            parsed)
 
845
 
 
846
 
 
847
class TestURL(TestCase):
 
848
 
 
849
    def test_parse_simple(self):
 
850
        parsed = urlutils.URL.from_string('http://example.com:80/one')
 
851
        self.assertEqual('http', parsed.scheme)
 
852
        self.assertIs(None, parsed.user)
 
853
        self.assertIs(None, parsed.password)
 
854
        self.assertEqual('example.com', parsed.host)
 
855
        self.assertEqual(80, parsed.port)
 
856
        self.assertEqual('/one', parsed.path)
 
857
 
 
858
    def test_ipv6(self):
 
859
        parsed = urlutils.URL.from_string('http://[1:2:3::40]/one')
 
860
        self.assertEqual('http', parsed.scheme)
 
861
        self.assertIs(None, parsed.port)
 
862
        self.assertIs(None, parsed.user)
 
863
        self.assertIs(None, parsed.password)
 
864
        self.assertEqual('1:2:3::40', parsed.host)
 
865
        self.assertEqual('/one', parsed.path)
 
866
 
 
867
    def test_ipv6_port(self):
 
868
        parsed = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
 
869
        self.assertEqual('http', parsed.scheme)
 
870
        self.assertEqual('1:2:3::40', parsed.host)
 
871
        self.assertIs(None, parsed.user)
 
872
        self.assertIs(None, parsed.password)
 
873
        self.assertEqual(80, parsed.port)
 
874
        self.assertEqual('/one', parsed.path)
 
875
 
 
876
    def test_quoted(self):
 
877
        parsed = urlutils.URL.from_string(
 
878
            'http://ro%62ey:h%40t@ex%41mple.com:2222/path')
 
879
        self.assertEqual(parsed.quoted_host, 'ex%41mple.com')
 
880
        self.assertEqual(parsed.host, 'exAmple.com')
 
881
        self.assertEqual(parsed.port, 2222)
 
882
        self.assertEqual(parsed.quoted_user, 'ro%62ey')
 
883
        self.assertEqual(parsed.user, 'robey')
 
884
        self.assertEqual(parsed.quoted_password, 'h%40t')
 
885
        self.assertEqual(parsed.password, 'h@t')
 
886
        self.assertEqual(parsed.path, '/path')
 
887
 
 
888
    def test_eq(self):
 
889
        parsed1 = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
 
890
        parsed2 = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
 
891
        self.assertEqual(parsed1, parsed2)
 
892
        self.assertEqual(parsed1, parsed1)
 
893
        parsed2.path = '/two'
 
894
        self.assertNotEqual(parsed1, parsed2)
 
895
 
 
896
    def test_repr(self):
 
897
        parsed = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
 
898
        self.assertEqual(
 
899
            "<URL('http', None, None, '1:2:3::40', 80, '/one')>",
 
900
            repr(parsed))
 
901
 
 
902
    def test_str(self):
 
903
        parsed = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
 
904
        self.assertEqual('http://[1:2:3::40]:80/one', str(parsed))
 
905
 
 
906
    def test__combine_paths(self):
 
907
        combine = urlutils.URL._combine_paths
 
908
        self.assertEqual('/home/sarah/project/foo',
 
909
                         combine('/home/sarah', 'project/foo'))
 
910
        self.assertEqual('/etc',
 
911
                         combine('/home/sarah', '../../etc'))
 
912
        self.assertEqual('/etc',
 
913
                         combine('/home/sarah', '../../../etc'))
 
914
        self.assertEqual('/etc',
 
915
                         combine('/home/sarah', '/etc'))
 
916
 
 
917
    def test_clone(self):
 
918
        url = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
 
919
        url1 = url.clone("two")
 
920
        self.assertEqual("/one/two", url1.path)
 
921
        url2 = url.clone("/two")
 
922
        self.assertEqual("/two", url2.path)
 
923
        url3 = url.clone()
 
924
        self.assertIsNot(url, url3)
 
925
        self.assertEqual(url, url3)
 
926
 
 
927
 
 
928
class TestFileRelpath(TestCase):
 
929
 
 
930
    # GZ 2011-11-18: A way to override all path handling functions to one
 
931
    #                platform or another for testing would be nice.
 
932
 
 
933
    def _with_posix_paths(self):
 
934
        self.overrideAttr(urlutils, "local_path_from_url",
 
935
            urlutils._posix_local_path_from_url)
 
936
        self.overrideAttr(urlutils, "MIN_ABS_FILEURL_LENGTH", len("file:///"))
 
937
        self.overrideAttr(osutils, "normpath", osutils._posix_normpath)
 
938
        self.overrideAttr(osutils, "abspath", osutils._posix_abspath)
 
939
        self.overrideAttr(osutils, "normpath", osutils._posix_normpath)
 
940
        self.overrideAttr(osutils, "pathjoin", osutils.posixpath.join)
 
941
        self.overrideAttr(osutils, "split", osutils.posixpath.split)
 
942
        self.overrideAttr(osutils, "MIN_ABS_PATHLENGTH", 1)
 
943
 
 
944
    def _with_win32_paths(self):
 
945
        self.overrideAttr(urlutils, "local_path_from_url",
 
946
            urlutils._win32_local_path_from_url)
 
947
        self.overrideAttr(urlutils, "MIN_ABS_FILEURL_LENGTH",
 
948
            urlutils.WIN32_MIN_ABS_FILEURL_LENGTH)
 
949
        self.overrideAttr(osutils, "abspath", osutils._win32_abspath)
 
950
        self.overrideAttr(osutils, "normpath", osutils._win32_normpath)
 
951
        self.overrideAttr(osutils, "pathjoin", osutils._win32_pathjoin)
 
952
        self.overrideAttr(osutils, "split", osutils.ntpath.split)
 
953
        self.overrideAttr(osutils, "MIN_ABS_PATHLENGTH", 3)
 
954
 
 
955
    def test_same_url_posix(self):
 
956
        self._with_posix_paths()
 
957
        self.assertEqual("",
 
958
            urlutils.file_relpath("file:///a", "file:///a"))
 
959
        self.assertEqual("",
 
960
            urlutils.file_relpath("file:///a", "file:///a/"))
 
961
        self.assertEqual("",
 
962
            urlutils.file_relpath("file:///a/", "file:///a"))
 
963
 
 
964
    def test_same_url_win32(self):
 
965
        self._with_win32_paths()
 
966
        self.assertEqual("",
 
967
            urlutils.file_relpath("file:///A:/", "file:///A:/"))
 
968
        self.assertEqual("",
 
969
            urlutils.file_relpath("file:///A|/", "file:///A:/"))
 
970
        self.assertEqual("",
 
971
            urlutils.file_relpath("file:///A:/b/", "file:///A:/b/"))
 
972
        self.assertEqual("",
 
973
            urlutils.file_relpath("file:///A:/b", "file:///A:/b/"))
 
974
        self.assertEqual("",
 
975
            urlutils.file_relpath("file:///A:/b/", "file:///A:/b"))
 
976
 
 
977
    def test_child_posix(self):
 
978
        self._with_posix_paths()
 
979
        self.assertEqual("b",
 
980
            urlutils.file_relpath("file:///a", "file:///a/b"))
 
981
        self.assertEqual("b",
 
982
            urlutils.file_relpath("file:///a/", "file:///a/b"))
 
983
        self.assertEqual("b/c",
 
984
            urlutils.file_relpath("file:///a", "file:///a/b/c"))
 
985
 
 
986
    def test_child_win32(self):
 
987
        self._with_win32_paths()
 
988
        self.assertEqual("b",
 
989
            urlutils.file_relpath("file:///A:/", "file:///A:/b"))
 
990
        self.assertEqual("b",
 
991
            urlutils.file_relpath("file:///A|/", "file:///A:/b"))
 
992
        self.assertEqual("c",
 
993
            urlutils.file_relpath("file:///A:/b", "file:///A:/b/c"))
 
994
        self.assertEqual("c",
 
995
            urlutils.file_relpath("file:///A:/b/", "file:///A:/b/c"))
 
996
        self.assertEqual("c/d",
 
997
            urlutils.file_relpath("file:///A:/b", "file:///A:/b/c/d"))
 
998
 
 
999
    def test_sibling_posix(self):
 
1000
        self._with_posix_paths()
 
1001
        self.assertRaises(PathNotChild,
 
1002
            urlutils.file_relpath, "file:///a/b", "file:///a/c")
 
1003
        self.assertRaises(PathNotChild,
 
1004
            urlutils.file_relpath, "file:///a/b/", "file:///a/c")
 
1005
        self.assertRaises(PathNotChild,
 
1006
            urlutils.file_relpath, "file:///a/b/", "file:///a/c/")
 
1007
 
 
1008
    def test_sibling_win32(self):
 
1009
        self._with_win32_paths()
 
1010
        self.assertRaises(PathNotChild,
 
1011
            urlutils.file_relpath, "file:///A:/b", "file:///A:/c")
 
1012
        self.assertRaises(PathNotChild,
 
1013
            urlutils.file_relpath, "file:///A:/b/", "file:///A:/c")
 
1014
        self.assertRaises(PathNotChild,
 
1015
            urlutils.file_relpath, "file:///A:/b/", "file:///A:/c/")
 
1016
 
 
1017
    def test_parent_posix(self):
 
1018
        self._with_posix_paths()
 
1019
        self.assertRaises(PathNotChild,
 
1020
            urlutils.file_relpath, "file:///a/b", "file:///a")
 
1021
        self.assertRaises(PathNotChild,
 
1022
            urlutils.file_relpath, "file:///a/b", "file:///a/")
 
1023
 
 
1024
    def test_parent_win32(self):
 
1025
        self._with_win32_paths()
 
1026
        self.assertRaises(PathNotChild,
 
1027
            urlutils.file_relpath, "file:///A:/b", "file:///A:/")
 
1028
        self.assertRaises(PathNotChild,
 
1029
            urlutils.file_relpath, "file:///A:/b/c", "file:///A:/b")
 
1030
 
 
1031
 
 
1032
class QuoteTests(TestCase):
 
1033
 
 
1034
    def test_quote(self):
 
1035
        self.assertEqual('abc%20def', urlutils.quote('abc def'))
 
1036
        self.assertEqual('abc%2Fdef', urlutils.quote('abc/def', safe=''))
 
1037
        self.assertEqual('abc/def', urlutils.quote('abc/def', safe='/'))
 
1038
 
 
1039
    def test_quote_tildes(self):
 
1040
        self.assertEqual('%7Efoo', urlutils.quote('~foo'))
 
1041
        self.assertEqual('~foo', urlutils.quote('~foo', safe='/~'))
 
1042
 
 
1043
    def test_unquote(self):
 
1044
        self.assertEqual('%', urlutils.unquote('%25'))
 
1045
        self.assertEqual('\xc3\xa5', urlutils.unquote('%C3%A5'))
 
1046
        self.assertEqual(u"\xe5", urlutils.unquote(u'\xe5'))