~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_urlutils.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-07-07 21:30:06 UTC
  • mfrom: (5333.1.2 better_pyqt_include)
  • Revision ID: pqm@pqm.ubuntu.com-20100707213006-lriphkkbzwwrl7ne
(jameinel) Use a better list of PyQt includes and excludes. (Gary van der
 Merwe)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 Canonical Ltd
 
1
# Copyright (C) 2006-2010 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
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
14
# along with this program; if not, write to the Free Software
15
 
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
"""Tests for the urlutils wrapper."""
18
18
 
19
19
import os
20
 
import re
21
20
import sys
22
21
 
23
22
from bzrlib import osutils, urlutils, win32utils
24
 
import bzrlib
25
 
from bzrlib.errors import InvalidURL, InvalidURLJoin
 
23
from bzrlib.errors import InvalidURL, InvalidURLJoin, InvalidRebaseURLs
26
24
from bzrlib.tests import TestCaseInTempDir, TestCase, TestSkipped
27
25
 
28
26
 
29
27
class TestUrlToPath(TestCase):
30
 
    
 
28
 
31
29
    def test_basename(self):
32
30
        # bzrlib.urlutils.basename
33
31
        # Test bzrlib.urlutils.split()
82
80
 
83
81
        # Local paths are assumed to *not* be escaped at all
84
82
        try:
85
 
            u'uni/\xb5'.encode(bzrlib.user_encoding)
 
83
            u'uni/\xb5'.encode(osutils.get_user_encoding())
86
84
        except UnicodeError:
87
 
            # locale cannot handle unicode 
 
85
            # locale cannot handle unicode
88
86
            pass
89
87
        else:
90
88
            norm_file('uni/%C2%B5', u'uni/\xb5')
158
156
        # Weird stuff
159
157
        # Can't have slashes or colons in the scheme
160
158
        test_one('/path/to/://foo', None)
161
 
        test_one('path:path://foo', None)
 
159
        test_one('scheme:stuff://foo', ('scheme', 'stuff://foo'))
162
160
        # Must have more than one character for scheme
163
161
        test_one('C://foo', None)
164
162
        test_one('ab://foo', ('ab', 'foo'))
197
195
            dirname('path/to/foo/', exclude_trailing_slash=False))
198
196
        self.assertEqual('path/..', dirname('path/../foo'))
199
197
        self.assertEqual('../path', dirname('../path/foo'))
 
198
    
 
199
    def test_is_url(self):
 
200
        self.assertTrue(urlutils.is_url('http://foo/bar'))
 
201
        self.assertTrue(urlutils.is_url('bzr+ssh://foo/bar'))
 
202
        self.assertTrue(urlutils.is_url('lp:foo/bar'))
 
203
        self.assertTrue(urlutils.is_url('file:///foo/bar'))
 
204
        self.assertFalse(urlutils.is_url(''))
 
205
        self.assertFalse(urlutils.is_url('foo'))
 
206
        self.assertFalse(urlutils.is_url('foo/bar'))
 
207
        self.assertFalse(urlutils.is_url('/foo'))
 
208
        self.assertFalse(urlutils.is_url('/foo/bar'))
 
209
        self.assertFalse(urlutils.is_url('C:/'))
 
210
        self.assertFalse(urlutils.is_url('C:/foo'))
 
211
        self.assertFalse(urlutils.is_url('C:/foo/bar'))
200
212
 
201
213
    def test_join(self):
202
214
        def test(expected, *args):
212
224
        test('http://foo/bar/baz', 'http://foo', 'bar/baz')
213
225
        test('http://foo/baz', 'http://foo', 'bar/../baz')
214
226
        test('http://foo/baz', 'http://foo/bar/', '../baz')
 
227
        test('lp:foo/bar', 'lp:foo', 'bar')
 
228
        test('lp:foo/bar/baz', 'lp:foo', 'bar/baz')
215
229
 
216
230
        # Absolute paths
217
231
        test('http://foo', 'http://foo') # abs url with nothing is preserved.
221
235
        test('http://bar/', 'http://foo', 'http://bar/')
222
236
        test('http://bar/a', 'http://foo', 'http://bar/a')
223
237
        test('http://bar/a/', 'http://foo', 'http://bar/a/')
 
238
        test('lp:bar', 'http://foo', 'lp:bar')
 
239
        test('lp:bar', 'lp:foo', 'lp:bar')
 
240
        test('file:///stuff', 'lp:foo', 'file:///stuff')
224
241
 
225
242
        # From a base path
226
243
        test('file:///foo', 'file:///', 'foo')
227
244
        test('file:///bar/foo', 'file:///bar/', 'foo')
228
245
        test('http://host/foo', 'http://host/', 'foo')
229
246
        test('http://host/', 'http://host', '')
230
 
        
 
247
 
231
248
        # Invalid joinings
232
249
        # Cannot go above root
233
250
        # Implicitly at root:
265
282
 
266
283
        # Test joining to a path with a trailing slash
267
284
        test('foo/bar', 'foo/', 'bar')
268
 
        
 
285
 
269
286
        # Invalid joinings
270
287
        # Cannot go above root
271
288
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '../baz')
272
289
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '..')
273
290
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '/..')
274
291
 
 
292
    def test_join_segment_parameters_raw(self):
 
293
        join_segment_parameters_raw = urlutils.join_segment_parameters_raw
 
294
        self.assertEquals("/somedir/path", 
 
295
            join_segment_parameters_raw("/somedir/path"))
 
296
        self.assertEquals("/somedir/path,rawdata", 
 
297
            join_segment_parameters_raw("/somedir/path", "rawdata"))
 
298
        self.assertRaises(InvalidURLJoin,
 
299
            join_segment_parameters_raw, "/somedir/path",
 
300
                "rawdata1,rawdata2,rawdata3")
 
301
        self.assertEquals("/somedir/path,bla,bar",
 
302
            join_segment_parameters_raw("/somedir/path", "bla", "bar"))
 
303
        self.assertEquals("/somedir,exist=some/path,bla,bar",
 
304
            join_segment_parameters_raw("/somedir,exist=some/path",
 
305
                "bla", "bar"))
 
306
        self.assertRaises(TypeError, join_segment_parameters_raw, 
 
307
            "/somepath", 42)
 
308
 
 
309
    def test_join_segment_parameters(self):
 
310
        join_segment_parameters = urlutils.join_segment_parameters
 
311
        self.assertEquals("/somedir/path", 
 
312
            join_segment_parameters("/somedir/path", {}))
 
313
        self.assertEquals("/somedir/path,key1=val1", 
 
314
            join_segment_parameters("/somedir/path", {"key1": "val1"}))
 
315
        self.assertRaises(InvalidURLJoin,
 
316
            join_segment_parameters, "/somedir/path",
 
317
            {"branch": "brr,brr,brr"})
 
318
        self.assertRaises(InvalidURLJoin,
 
319
            join_segment_parameters, "/somedir/path", {"key1=val1": "val2"})
 
320
        self.assertEquals("/somedir/path,key1=val1,key2=val2",
 
321
            join_segment_parameters("/somedir/path", {
 
322
                "key1": "val1", "key2": "val2"}))
 
323
        self.assertEquals("/somedir/path,key1=val1,key2=val2",
 
324
            join_segment_parameters("/somedir/path,key1=val1", {
 
325
                "key2": "val2"}))
 
326
        self.assertEquals("/somedir/path,key1=val2",
 
327
            join_segment_parameters("/somedir/path,key1=val1", {
 
328
                "key1": "val2"}))
 
329
        self.assertEquals("/somedir,exist=some/path,key1=val1",
 
330
            join_segment_parameters("/somedir,exist=some/path",
 
331
                {"key1": "val1"}))
 
332
        self.assertEquals("/,key1=val1,key2=val2",
 
333
            join_segment_parameters("/,key1=val1", {"key2": "val2"}))
 
334
        self.assertRaises(TypeError,
 
335
            join_segment_parameters, "/,key1=val1", {"foo": 42})
 
336
 
275
337
    def test_function_type(self):
276
338
        if sys.platform == 'win32':
277
339
            self.assertEqual(urlutils._win32_local_path_to_url, urlutils.local_path_to_url)
291
353
            raise TestSkipped("local encoding cannot handle unicode")
292
354
 
293
355
        self.assertEqual('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
 
356
        self.assertFalse(isinstance(result, unicode))
294
357
 
295
358
    def test_posix_local_path_from_url(self):
296
359
        from_url = urlutils._posix_local_path_from_url
300
363
            from_url('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
301
364
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
302
365
            from_url('file:///path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
 
366
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
 
367
            from_url('file://localhost/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
303
368
 
304
369
        self.assertRaises(InvalidURL, from_url, '/path/to/foo')
 
370
        self.assertRaises(
 
371
            InvalidURL, from_url,
 
372
            'file://remotehost/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s')
305
373
 
306
374
    def test_win32_local_path_to_url(self):
307
375
        to_url = urlutils._win32_local_path_to_url
316
384
        self.assertEqual('file:///C:/path/to/f%20oo',
317
385
            to_url('C:/path/to/f oo'))
318
386
 
 
387
        self.assertEqual('file:///', to_url('/'))
 
388
 
319
389
        try:
320
390
            result = to_url(u'd:/path/to/r\xe4ksm\xf6rg\xe5s')
321
391
        except UnicodeError:
322
392
            raise TestSkipped("local encoding cannot handle unicode")
323
393
 
324
394
        self.assertEqual('file:///D:/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
 
395
        self.assertFalse(isinstance(result, unicode))
325
396
 
326
397
    def test_win32_unc_path_to_url(self):
327
398
        to_url = urlutils._win32_local_path_to_url
336
407
            raise TestSkipped("local encoding cannot handle unicode")
337
408
 
338
409
        self.assertEqual('file://HOST/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
339
 
 
 
410
        self.assertFalse(isinstance(result, unicode))
340
411
 
341
412
    def test_win32_local_path_from_url(self):
342
413
        from_url = urlutils._win32_local_path_from_url
346
417
            from_url('file:///d|/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
347
418
        self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
348
419
            from_url('file:///d:/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
 
420
        self.assertEqual('/', from_url('file:///'))
349
421
 
350
422
        self.assertRaises(InvalidURL, from_url, '/path/to/foo')
351
423
        # Not a valid _win32 url, no drive letter
404
476
        self.assertEqual(('path/..', 'foo'), split('path/../foo'))
405
477
        self.assertEqual(('../path', 'foo'), split('../path/foo'))
406
478
 
 
479
    def test_split_segment_parameters_raw(self):
 
480
        split_segment_parameters_raw = urlutils.split_segment_parameters_raw
 
481
        self.assertEquals(("/some/path", []),
 
482
            split_segment_parameters_raw("/some/path"))
 
483
        self.assertEquals(("/some/path", ["tip"]),
 
484
            split_segment_parameters_raw("/some/path,tip"))
 
485
        self.assertEquals(("/some,dir/path", ["tip"]),
 
486
            split_segment_parameters_raw("/some,dir/path,tip"))
 
487
        self.assertEquals(("/somedir/path", ["heads%2Ftip"]),
 
488
            split_segment_parameters_raw("/somedir/path,heads%2Ftip"))
 
489
        self.assertEquals(("/somedir/path", ["heads%2Ftip", "bar"]),
 
490
            split_segment_parameters_raw("/somedir/path,heads%2Ftip,bar"))
 
491
        self.assertEquals(("/", ["key1=val1"]),
 
492
            split_segment_parameters_raw(",key1=val1"))
 
493
        self.assertEquals(("foo/", ["key1=val1"]),
 
494
            split_segment_parameters_raw("foo/,key1=val1"))
 
495
        self.assertEquals(("foo/base,la=bla/other/elements", []),
 
496
            split_segment_parameters_raw("foo/base,la=bla/other/elements"))
 
497
        self.assertEquals(("foo/base,la=bla/other/elements", ["a=b"]),
 
498
            split_segment_parameters_raw("foo/base,la=bla/other/elements,a=b"))
 
499
 
 
500
    def test_split_segment_parameters(self):
 
501
        split_segment_parameters = urlutils.split_segment_parameters
 
502
        self.assertEquals(("/some/path", {}),
 
503
            split_segment_parameters("/some/path"))
 
504
        self.assertEquals(("/some/path", {"branch": "tip"}),
 
505
            split_segment_parameters("/some/path,branch=tip"))
 
506
        self.assertEquals(("/some,dir/path", {"branch": "tip"}),
 
507
            split_segment_parameters("/some,dir/path,branch=tip"))
 
508
        self.assertEquals(("/somedir/path", {"ref": "heads%2Ftip"}),
 
509
            split_segment_parameters("/somedir/path,ref=heads%2Ftip"))
 
510
        self.assertEquals(("/somedir/path",
 
511
            {"ref": "heads%2Ftip", "key1": "val1"}),
 
512
            split_segment_parameters(
 
513
                "/somedir/path,ref=heads%2Ftip,key1=val1"))
 
514
        self.assertEquals(("/somedir/path", {"ref": "heads%2F=tip"}),
 
515
            split_segment_parameters("/somedir/path,ref=heads%2F=tip"))
 
516
        self.assertEquals(("/", {"key1": "val1"}),
 
517
            split_segment_parameters(",key1=val1"))
 
518
        self.assertEquals(("foo/", {"key1": "val1"}),
 
519
            split_segment_parameters("foo/,key1=val1"))
 
520
        self.assertEquals(("foo/base,key1=val1/other/elements", {}),
 
521
            split_segment_parameters("foo/base,key1=val1/other/elements"))
 
522
        self.assertEquals(("foo/base,key1=val1/other/elements",
 
523
            {"key2": "val2"}), split_segment_parameters(
 
524
                "foo/base,key1=val1/other/elements,key2=val2"))
 
525
 
407
526
    def test_win32_strip_local_trailing_slash(self):
408
527
        strip = urlutils._win32_strip_local_trailing_slash
409
528
        self.assertEqual('file://', strip('file://'))
491
610
    def test_escape(self):
492
611
        self.assertEqual('%25', urlutils.escape('%'))
493
612
        self.assertEqual('%C3%A5', urlutils.escape(u'\xe5'))
 
613
        self.assertFalse(isinstance(urlutils.escape(u'\xe5'), unicode))
 
614
 
 
615
    def test_escape_tildes(self):
 
616
        self.assertEqual('~foo', urlutils.escape('~foo'))
494
617
 
495
618
    def test_unescape(self):
496
619
        self.assertEqual('%', urlutils.unescape('%25'))
508
631
        def test(expected, base, other):
509
632
            result = urlutils.relative_url(base, other)
510
633
            self.assertEqual(expected, result)
511
 
            
 
634
 
512
635
        test('a', 'http://host/', 'http://host/a')
513
636
        test('http://entirely/different', 'sftp://host/branch',
514
637
                    'http://entirely/different')
523
646
                    'sftp://host/home/jelmer/branch/2b')
524
647
        test('../../branch/feature/%2b', 'http://host/home/jelmer/bar/%2b',
525
648
                    'http://host/home/jelmer/branch/feature/%2b')
526
 
        test('../../branch/feature/2b', 'http://host/home/jelmer/bar/2b/', 
 
649
        test('../../branch/feature/2b', 'http://host/home/jelmer/bar/2b/',
527
650
                    'http://host/home/jelmer/branch/feature/2b')
528
651
        # relative_url should preserve a trailing slash
529
652
        test('../../branch/feature/2b/', 'http://host/home/jelmer/bar/2b/',
541
664
        #test('.', 'http://host/', 'http://host')
542
665
        test('http://host', 'http://host/', 'http://host')
543
666
 
 
667
        # On Windows file:///C:/path/to and file:///D:/other/path
 
668
        # should not use relative url over the non-existent '/' directory.
 
669
        if sys.platform == 'win32':
 
670
            # on the same drive
 
671
            test('../../other/path',
 
672
                'file:///C:/path/to', 'file:///C:/other/path')
 
673
            #~next two tests is failed, i.e. urlutils.relative_url expects
 
674
            #~to see normalized file URLs?
 
675
            #~test('../../other/path',
 
676
            #~    'file:///C:/path/to', 'file:///c:/other/path')
 
677
            #~test('../../other/path',
 
678
            #~    'file:///C:/path/to', 'file:///C|/other/path')
 
679
 
 
680
            # check UNC paths too
 
681
            test('../../other/path',
 
682
                'file://HOST/base/path/to', 'file://HOST/base/other/path')
 
683
            # on different drives
 
684
            test('file:///D:/other/path',
 
685
                'file:///C:/path/to', 'file:///D:/other/path')
 
686
            # TODO: strictly saying in UNC path //HOST/base is full analog
 
687
            # of drive letter for hard disk, and this situation is also
 
688
            # should be exception from rules. [bialix 20071221]
 
689
 
544
690
 
545
691
class TestCwdToURL(TestCaseInTempDir):
546
692
    """Test that local_path_to_url works base on the cwd"""
564
710
 
565
711
        os.chdir(u'dod\xe9')
566
712
 
567
 
        # On Mac OSX this directory is actually: 
 
713
        # On Mac OSX this directory is actually:
568
714
        #   u'/dode\u0301' => '/dode\xcc\x81
569
 
        # but we should normalize it back to 
 
715
        # but we should normalize it back to
570
716
        #   u'/dod\xe9' => '/dod\xc3\xa9'
571
717
        url = urlutils.local_path_to_url('.')
572
718
        self.assertEndsWith(url, '/dod%C3%A9')
588
734
        self.assertEqual("bar", derive("http://foo/bar"))
589
735
        self.assertEqual("bar", derive("bzr+ssh://foo/bar"))
590
736
        self.assertEqual("foo-bar", derive("lp:foo-bar"))
 
737
 
 
738
 
 
739
class TestRebaseURL(TestCase):
 
740
    """Test the behavior of rebase_url."""
 
741
 
 
742
    def test_non_relative(self):
 
743
        result = urlutils.rebase_url('file://foo', 'file://foo',
 
744
                                     'file://foo/bar')
 
745
        self.assertEqual('file://foo', result)
 
746
        result = urlutils.rebase_url('/foo', 'file://foo',
 
747
                                     'file://foo/bar')
 
748
        self.assertEqual('/foo', result)
 
749
 
 
750
    def test_different_ports(self):
 
751
        e = self.assertRaises(InvalidRebaseURLs, urlutils.rebase_url,
 
752
                              'foo', 'http://bar:80', 'http://bar:81')
 
753
        self.assertEqual(str(e), "URLs differ by more than path:"
 
754
                         " 'http://bar:80' and 'http://bar:81'")
 
755
 
 
756
    def test_different_hosts(self):
 
757
        e = self.assertRaises(InvalidRebaseURLs, urlutils.rebase_url,
 
758
                              'foo', 'http://bar', 'http://baz')
 
759
        self.assertEqual(str(e), "URLs differ by more than path: 'http://bar'"
 
760
                         " and 'http://baz'")
 
761
 
 
762
    def test_different_protocol(self):
 
763
        e = self.assertRaises(InvalidRebaseURLs, urlutils.rebase_url,
 
764
                              'foo', 'http://bar', 'ftp://bar')
 
765
        self.assertEqual(str(e), "URLs differ by more than path: 'http://bar'"
 
766
                         " and 'ftp://bar'")
 
767
 
 
768
    def test_rebase_success(self):
 
769
        self.assertEqual('../bar', urlutils.rebase_url('bar', 'http://baz/',
 
770
                         'http://baz/qux'))
 
771
        self.assertEqual('qux/bar', urlutils.rebase_url('bar',
 
772
                         'http://baz/qux', 'http://baz/'))
 
773
        self.assertEqual('.', urlutils.rebase_url('foo',
 
774
                         'http://bar/', 'http://bar/foo/'))
 
775
        self.assertEqual('qux/bar', urlutils.rebase_url('../bar',
 
776
                         'http://baz/qux/foo', 'http://baz/'))
 
777
 
 
778
    def test_determine_relative_path(self):
 
779
        self.assertEqual('../../baz/bar',
 
780
                         urlutils.determine_relative_path(
 
781
                         '/qux/quxx', '/baz/bar'))
 
782
        self.assertEqual('..',
 
783
                         urlutils.determine_relative_path(
 
784
                         '/bar/baz', '/bar'))
 
785
        self.assertEqual('baz',
 
786
                         urlutils.determine_relative_path(
 
787
                         '/bar', '/bar/baz'))
 
788
        self.assertEqual('.', urlutils.determine_relative_path(
 
789
                         '/bar', '/bar'))
 
790
 
 
791
 
 
792
class TestParseURL(TestCase):
 
793
 
 
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'))