~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_urlutils.py

  • Committer: Jelmer Vernooij
  • Date: 2011-02-26 15:39:49 UTC
  • mto: (5691.1.1 bzr.dev)
  • mto: This revision was merged to the branch mainline in revision 5692.
  • Revision ID: jelmer@samba.org-20110226153949-o0fk909b30g7z570
Fix the use of "bzr tags" in branches with ghosts in their mainline /and/ tags on revisions not in the branch ancestry.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by 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
 
from bzrlib import osutils, urlutils
24
 
import bzrlib
25
 
from bzrlib.errors import InvalidURL, InvalidURLJoin
 
22
from bzrlib import osutils, urlutils, win32utils
 
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')
115
113
        eq('http://host/ab/%C2%B5/%C2%B5',
116
114
            normalize_url(u'http://host/ab/%C2%B5/\xb5'))
117
115
 
 
116
        # Unescape characters that don't need to be escaped
 
117
        eq('http://host/~bob%2525-._',
 
118
                normalize_url('http://host/%7Ebob%2525%2D%2E%5F'))
 
119
        eq('http://host/~bob%2525-._',
 
120
                normalize_url(u'http://host/%7Ebob%2525%2D%2E%5F'))
 
121
 
118
122
        # Normalize verifies URLs when they are not unicode
119
123
        # (indicating they did not come from the user)
120
124
        self.assertRaises(InvalidURL, normalize_url, 'http://host/\xb5')
152
156
        # Weird stuff
153
157
        # Can't have slashes or colons in the scheme
154
158
        test_one('/path/to/://foo', None)
155
 
        test_one('path:path://foo', None)
 
159
        test_one('scheme:stuff://foo', ('scheme', 'stuff://foo'))
156
160
        # Must have more than one character for scheme
157
161
        test_one('C://foo', None)
158
162
        test_one('ab://foo', ('ab', 'foo'))
191
195
            dirname('path/to/foo/', exclude_trailing_slash=False))
192
196
        self.assertEqual('path/..', dirname('path/../foo'))
193
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'))
194
212
 
195
213
    def test_join(self):
196
214
        def test(expected, *args):
197
215
            joined = urlutils.join(*args)
198
216
            self.assertEqual(expected, joined)
199
217
 
200
 
        # Test a single element
201
 
        test('foo', 'foo')
202
 
 
203
218
        # Test relative path joining
 
219
        test('foo', 'foo') # relative fragment with nothing is preserved.
204
220
        test('foo/bar', 'foo', 'bar')
205
221
        test('http://foo/bar', 'http://foo', 'bar')
206
222
        test('http://foo/bar', 'http://foo', '.', 'bar')
207
223
        test('http://foo/baz', 'http://foo', 'bar', '../baz')
208
224
        test('http://foo/bar/baz', 'http://foo', 'bar/baz')
209
225
        test('http://foo/baz', 'http://foo', 'bar/../baz')
 
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')
210
229
 
211
230
        # Absolute paths
 
231
        test('http://foo', 'http://foo') # abs url with nothing is preserved.
212
232
        test('http://bar', 'http://foo', 'http://bar')
213
233
        test('sftp://bzr/foo', 'http://foo', 'bar', 'sftp://bzr/foo')
214
234
        test('file:///bar', 'foo', 'file:///bar')
 
235
        test('http://bar/', 'http://foo', 'http://bar/')
 
236
        test('http://bar/a', 'http://foo', 'http://bar/a')
 
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')
215
241
 
216
242
        # From a base path
217
243
        test('file:///foo', 'file:///', 'foo')
218
244
        test('file:///bar/foo', 'file:///bar/', 'foo')
219
245
        test('http://host/foo', 'http://host/', 'foo')
220
246
        test('http://host/', 'http://host', '')
221
 
        
 
247
 
222
248
        # Invalid joinings
223
249
        # Cannot go above root
 
250
        # Implicitly at root:
224
251
        self.assertRaises(InvalidURLJoin, urlutils.join,
225
252
                'http://foo', '../baz')
 
253
        self.assertRaises(InvalidURLJoin, urlutils.join,
 
254
                'http://foo', '/..')
 
255
        # Joining from a path explicitly under the root.
 
256
        self.assertRaises(InvalidURLJoin, urlutils.join,
 
257
                'http://foo/a', '../../b')
 
258
 
 
259
    def test_joinpath(self):
 
260
        def test(expected, *args):
 
261
            joined = urlutils.joinpath(*args)
 
262
            self.assertEqual(expected, joined)
 
263
 
 
264
        # Test a single element
 
265
        test('foo', 'foo')
 
266
 
 
267
        # Test relative path joining
 
268
        test('foo/bar', 'foo', 'bar')
 
269
        test('foo/bar', 'foo', '.', 'bar')
 
270
        test('foo/baz', 'foo', 'bar', '../baz')
 
271
        test('foo/bar/baz', 'foo', 'bar/baz')
 
272
        test('foo/baz', 'foo', 'bar/../baz')
 
273
 
 
274
        # Test joining to an absolute path
 
275
        test('/foo', '/foo')
 
276
        test('/foo', '/foo', '.')
 
277
        test('/foo/bar', '/foo', 'bar')
 
278
        test('/', '/foo', '..')
 
279
 
 
280
        # Test joining with an absolute path
 
281
        test('/bar', 'foo', '/bar')
 
282
 
 
283
        # Test joining to a path with a trailing slash
 
284
        test('foo/bar', 'foo/', 'bar')
 
285
 
 
286
        # Invalid joinings
 
287
        # Cannot go above root
 
288
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '../baz')
 
289
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '..')
 
290
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '/..')
 
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})
226
336
 
227
337
    def test_function_type(self):
228
338
        if sys.platform == 'win32':
243
353
            raise TestSkipped("local encoding cannot handle unicode")
244
354
 
245
355
        self.assertEqual('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
 
356
        self.assertFalse(isinstance(result, unicode))
246
357
 
247
358
    def test_posix_local_path_from_url(self):
248
359
        from_url = urlutils._posix_local_path_from_url
252
363
            from_url('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
253
364
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
254
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'))
255
368
 
256
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')
257
373
 
258
374
    def test_win32_local_path_to_url(self):
259
375
        to_url = urlutils._win32_local_path_to_url
268
384
        self.assertEqual('file:///C:/path/to/f%20oo',
269
385
            to_url('C:/path/to/f oo'))
270
386
 
 
387
        self.assertEqual('file:///', to_url('/'))
 
388
 
271
389
        try:
272
390
            result = to_url(u'd:/path/to/r\xe4ksm\xf6rg\xe5s')
273
391
        except UnicodeError:
274
392
            raise TestSkipped("local encoding cannot handle unicode")
275
393
 
276
394
        self.assertEqual('file:///D:/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
 
395
        self.assertFalse(isinstance(result, unicode))
 
396
 
 
397
    def test_win32_unc_path_to_url(self):
 
398
        to_url = urlutils._win32_local_path_to_url
 
399
        self.assertEqual('file://HOST/path',
 
400
            to_url(r'\\HOST\path'))
 
401
        self.assertEqual('file://HOST/path',
 
402
            to_url('//HOST/path'))
 
403
 
 
404
        try:
 
405
            result = to_url(u'//HOST/path/to/r\xe4ksm\xf6rg\xe5s')
 
406
        except UnicodeError:
 
407
            raise TestSkipped("local encoding cannot handle unicode")
 
408
 
 
409
        self.assertEqual('file://HOST/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
 
410
        self.assertFalse(isinstance(result, unicode))
277
411
 
278
412
    def test_win32_local_path_from_url(self):
279
413
        from_url = urlutils._win32_local_path_from_url
283
417
            from_url('file:///d|/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
284
418
        self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
285
419
            from_url('file:///d:/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
 
420
        self.assertEqual('/', from_url('file:///'))
286
421
 
 
422
        self.assertRaises(InvalidURL, from_url, 'file:///C:')
 
423
        self.assertRaises(InvalidURL, from_url, 'file:///c')
287
424
        self.assertRaises(InvalidURL, from_url, '/path/to/foo')
288
425
        # Not a valid _win32 url, no drive letter
289
426
        self.assertRaises(InvalidURL, from_url, 'file:///path/to/foo')
290
427
 
291
 
    def test__win32_extract_drive_letter(self):
 
428
    def test_win32_unc_path_from_url(self):
 
429
        from_url = urlutils._win32_local_path_from_url
 
430
        self.assertEqual('//HOST/path', from_url('file://HOST/path'))
 
431
        # despite IE allows 2, 4, 5 and 6 slashes in URL to another machine
 
432
        # we want to use only 2 slashes
 
433
        # Firefox understand only 5 slashes in URL, but it's ugly
 
434
        self.assertRaises(InvalidURL, from_url, 'file:////HOST/path')
 
435
        self.assertRaises(InvalidURL, from_url, 'file://///HOST/path')
 
436
        self.assertRaises(InvalidURL, from_url, 'file://////HOST/path')
 
437
        # check for file://C:/ instead of file:///C:/
 
438
        self.assertRaises(InvalidURL, from_url, 'file://C:/path')
 
439
 
 
440
    def test_win32_extract_drive_letter(self):
292
441
        extract = urlutils._win32_extract_drive_letter
293
442
        self.assertEqual(('file:///C:', '/foo'), extract('file://', '/C:/foo'))
294
443
        self.assertEqual(('file:///d|', '/path'), extract('file://', '/d|/path'))
329
478
        self.assertEqual(('path/..', 'foo'), split('path/../foo'))
330
479
        self.assertEqual(('../path', 'foo'), split('../path/foo'))
331
480
 
332
 
    def test__win32_strip_local_trailing_slash(self):
 
481
    def test_split_segment_parameters_raw(self):
 
482
        split_segment_parameters_raw = urlutils.split_segment_parameters_raw
 
483
        self.assertEquals(("/some/path", []),
 
484
            split_segment_parameters_raw("/some/path"))
 
485
        self.assertEquals(("/some/path", ["tip"]),
 
486
            split_segment_parameters_raw("/some/path,tip"))
 
487
        self.assertEquals(("/some,dir/path", ["tip"]),
 
488
            split_segment_parameters_raw("/some,dir/path,tip"))
 
489
        self.assertEquals(("/somedir/path", ["heads%2Ftip"]),
 
490
            split_segment_parameters_raw("/somedir/path,heads%2Ftip"))
 
491
        self.assertEquals(("/somedir/path", ["heads%2Ftip", "bar"]),
 
492
            split_segment_parameters_raw("/somedir/path,heads%2Ftip,bar"))
 
493
        self.assertEquals(("/", ["key1=val1"]),
 
494
            split_segment_parameters_raw(",key1=val1"))
 
495
        self.assertEquals(("foo/", ["key1=val1"]),
 
496
            split_segment_parameters_raw("foo/,key1=val1"))
 
497
        self.assertEquals(("foo/base,la=bla/other/elements", []),
 
498
            split_segment_parameters_raw("foo/base,la=bla/other/elements"))
 
499
        self.assertEquals(("foo/base,la=bla/other/elements", ["a=b"]),
 
500
            split_segment_parameters_raw("foo/base,la=bla/other/elements,a=b"))
 
501
 
 
502
    def test_split_segment_parameters(self):
 
503
        split_segment_parameters = urlutils.split_segment_parameters
 
504
        self.assertEquals(("/some/path", {}),
 
505
            split_segment_parameters("/some/path"))
 
506
        self.assertEquals(("/some/path", {"branch": "tip"}),
 
507
            split_segment_parameters("/some/path,branch=tip"))
 
508
        self.assertEquals(("/some,dir/path", {"branch": "tip"}),
 
509
            split_segment_parameters("/some,dir/path,branch=tip"))
 
510
        self.assertEquals(("/somedir/path", {"ref": "heads%2Ftip"}),
 
511
            split_segment_parameters("/somedir/path,ref=heads%2Ftip"))
 
512
        self.assertEquals(("/somedir/path",
 
513
            {"ref": "heads%2Ftip", "key1": "val1"}),
 
514
            split_segment_parameters(
 
515
                "/somedir/path,ref=heads%2Ftip,key1=val1"))
 
516
        self.assertEquals(("/somedir/path", {"ref": "heads%2F=tip"}),
 
517
            split_segment_parameters("/somedir/path,ref=heads%2F=tip"))
 
518
        self.assertEquals(("/", {"key1": "val1"}),
 
519
            split_segment_parameters(",key1=val1"))
 
520
        self.assertEquals(("foo/", {"key1": "val1"}),
 
521
            split_segment_parameters("foo/,key1=val1"))
 
522
        self.assertEquals(("foo/base,key1=val1/other/elements", {}),
 
523
            split_segment_parameters("foo/base,key1=val1/other/elements"))
 
524
        self.assertEquals(("foo/base,key1=val1/other/elements",
 
525
            {"key2": "val2"}), split_segment_parameters(
 
526
                "foo/base,key1=val1/other/elements,key2=val2"))
 
527
 
 
528
    def test_win32_strip_local_trailing_slash(self):
333
529
        strip = urlutils._win32_strip_local_trailing_slash
334
530
        self.assertEqual('file://', strip('file://'))
335
531
        self.assertEqual('file:///', strip('file:///'))
416
612
    def test_escape(self):
417
613
        self.assertEqual('%25', urlutils.escape('%'))
418
614
        self.assertEqual('%C3%A5', urlutils.escape(u'\xe5'))
 
615
        self.assertFalse(isinstance(urlutils.escape(u'\xe5'), unicode))
 
616
 
 
617
    def test_escape_tildes(self):
 
618
        self.assertEqual('~foo', urlutils.escape('~foo'))
419
619
 
420
620
    def test_unescape(self):
421
621
        self.assertEqual('%', urlutils.unescape('%25'))
433
633
        def test(expected, base, other):
434
634
            result = urlutils.relative_url(base, other)
435
635
            self.assertEqual(expected, result)
436
 
            
 
636
 
437
637
        test('a', 'http://host/', 'http://host/a')
438
638
        test('http://entirely/different', 'sftp://host/branch',
439
639
                    'http://entirely/different')
448
648
                    'sftp://host/home/jelmer/branch/2b')
449
649
        test('../../branch/feature/%2b', 'http://host/home/jelmer/bar/%2b',
450
650
                    'http://host/home/jelmer/branch/feature/%2b')
451
 
        test('../../branch/feature/2b', 'http://host/home/jelmer/bar/2b/', 
 
651
        test('../../branch/feature/2b', 'http://host/home/jelmer/bar/2b/',
452
652
                    'http://host/home/jelmer/branch/feature/2b')
453
653
        # relative_url should preserve a trailing slash
454
654
        test('../../branch/feature/2b/', 'http://host/home/jelmer/bar/2b/',
466
666
        #test('.', 'http://host/', 'http://host')
467
667
        test('http://host', 'http://host/', 'http://host')
468
668
 
 
669
        # On Windows file:///C:/path/to and file:///D:/other/path
 
670
        # should not use relative url over the non-existent '/' directory.
 
671
        if sys.platform == 'win32':
 
672
            # on the same drive
 
673
            test('../../other/path',
 
674
                'file:///C:/path/to', 'file:///C:/other/path')
 
675
            #~next two tests is failed, i.e. urlutils.relative_url expects
 
676
            #~to see normalized file URLs?
 
677
            #~test('../../other/path',
 
678
            #~    'file:///C:/path/to', 'file:///c:/other/path')
 
679
            #~test('../../other/path',
 
680
            #~    'file:///C:/path/to', 'file:///C|/other/path')
 
681
 
 
682
            # check UNC paths too
 
683
            test('../../other/path',
 
684
                'file://HOST/base/path/to', 'file://HOST/base/other/path')
 
685
            # on different drives
 
686
            test('file:///D:/other/path',
 
687
                'file:///C:/path/to', 'file:///D:/other/path')
 
688
            # TODO: strictly saying in UNC path //HOST/base is full analog
 
689
            # of drive letter for hard disk, and this situation is also
 
690
            # should be exception from rules. [bialix 20071221]
 
691
 
469
692
 
470
693
class TestCwdToURL(TestCaseInTempDir):
471
694
    """Test that local_path_to_url works base on the cwd"""
479
702
        self.assertEndsWith(url, '/mytest')
480
703
 
481
704
    def test_non_ascii(self):
 
705
        if win32utils.winver == 'Windows 98':
 
706
            raise TestSkipped('Windows 98 cannot handle unicode filenames')
 
707
 
482
708
        try:
483
709
            os.mkdir(u'dod\xe9')
484
710
        except UnicodeError:
486
712
 
487
713
        os.chdir(u'dod\xe9')
488
714
 
489
 
        # On Mac OSX this directory is actually: 
 
715
        # On Mac OSX this directory is actually:
490
716
        #   u'/dode\u0301' => '/dode\xcc\x81
491
 
        # but we should normalize it back to 
 
717
        # but we should normalize it back to
492
718
        #   u'/dod\xe9' => '/dod\xc3\xa9'
493
719
        url = urlutils.local_path_to_url('.')
494
720
        self.assertEndsWith(url, '/dod%C3%A9')
 
721
 
 
722
 
 
723
class TestDeriveToLocation(TestCase):
 
724
    """Test that the mapping of FROM_LOCATION to TO_LOCATION works."""
 
725
 
 
726
    def test_to_locations_derived_from_paths(self):
 
727
        derive = urlutils.derive_to_location
 
728
        self.assertEqual("bar", derive("bar"))
 
729
        self.assertEqual("bar", derive("../bar"))
 
730
        self.assertEqual("bar", derive("/foo/bar"))
 
731
        self.assertEqual("bar", derive("c:/foo/bar"))
 
732
        self.assertEqual("bar", derive("c:bar"))
 
733
 
 
734
    def test_to_locations_derived_from_urls(self):
 
735
        derive = urlutils.derive_to_location
 
736
        self.assertEqual("bar", derive("http://foo/bar"))
 
737
        self.assertEqual("bar", derive("bzr+ssh://foo/bar"))
 
738
        self.assertEqual("foo-bar", derive("lp:foo-bar"))
 
739
 
 
740
 
 
741
class TestRebaseURL(TestCase):
 
742
    """Test the behavior of rebase_url."""
 
743
 
 
744
    def test_non_relative(self):
 
745
        result = urlutils.rebase_url('file://foo', 'file://foo',
 
746
                                     'file://foo/bar')
 
747
        self.assertEqual('file://foo', result)
 
748
        result = urlutils.rebase_url('/foo', 'file://foo',
 
749
                                     'file://foo/bar')
 
750
        self.assertEqual('/foo', result)
 
751
 
 
752
    def test_different_ports(self):
 
753
        e = self.assertRaises(InvalidRebaseURLs, urlutils.rebase_url,
 
754
                              'foo', 'http://bar:80', 'http://bar:81')
 
755
        self.assertEqual(str(e), "URLs differ by more than path:"
 
756
                         " 'http://bar:80' and 'http://bar:81'")
 
757
 
 
758
    def test_different_hosts(self):
 
759
        e = self.assertRaises(InvalidRebaseURLs, urlutils.rebase_url,
 
760
                              'foo', 'http://bar', 'http://baz')
 
761
        self.assertEqual(str(e), "URLs differ by more than path: 'http://bar'"
 
762
                         " and 'http://baz'")
 
763
 
 
764
    def test_different_protocol(self):
 
765
        e = self.assertRaises(InvalidRebaseURLs, urlutils.rebase_url,
 
766
                              'foo', 'http://bar', 'ftp://bar')
 
767
        self.assertEqual(str(e), "URLs differ by more than path: 'http://bar'"
 
768
                         " and 'ftp://bar'")
 
769
 
 
770
    def test_rebase_success(self):
 
771
        self.assertEqual('../bar', urlutils.rebase_url('bar', 'http://baz/',
 
772
                         'http://baz/qux'))
 
773
        self.assertEqual('qux/bar', urlutils.rebase_url('bar',
 
774
                         'http://baz/qux', 'http://baz/'))
 
775
        self.assertEqual('.', urlutils.rebase_url('foo',
 
776
                         'http://bar/', 'http://bar/foo/'))
 
777
        self.assertEqual('qux/bar', urlutils.rebase_url('../bar',
 
778
                         'http://baz/qux/foo', 'http://baz/'))
 
779
 
 
780
    def test_determine_relative_path(self):
 
781
        self.assertEqual('../../baz/bar',
 
782
                         urlutils.determine_relative_path(
 
783
                         '/qux/quxx', '/baz/bar'))
 
784
        self.assertEqual('..',
 
785
                         urlutils.determine_relative_path(
 
786
                         '/bar/baz', '/bar'))
 
787
        self.assertEqual('baz',
 
788
                         urlutils.determine_relative_path(
 
789
                         '/bar', '/bar/baz'))
 
790
        self.assertEqual('.', urlutils.determine_relative_path(
 
791
                         '/bar', '/bar'))
 
792
 
 
793
 
 
794
class TestParseURL(TestCase):
 
795
 
 
796
    def test_parse_url(self):
 
797
        self.assertEqual(urlutils.parse_url('http://example.com:80/one'),
 
798
            ('http', None, None, 'example.com', 80, '/one'))
 
799
        self.assertEqual(urlutils.parse_url('http://[1:2:3::40]/one'),
 
800
                ('http', None, None, '1:2:3::40', None, '/one'))
 
801
        self.assertEqual(urlutils.parse_url('http://[1:2:3::40]:80/one'),
 
802
                ('http', None, None, '1:2:3::40', 80, '/one'))