~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_urlutils.py

  • Committer: Wouter van Heyst
  • Date: 2006-06-07 16:05:27 UTC
  • mto: This revision was merged to the branch mainline in revision 1752.
  • Revision ID: larstiq@larstiq.dyndns.org-20060607160527-2b3649154d0e2e84
more code cleanup

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 Canonical Ltd
 
1
# Copyright (C) 2005 by 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
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, win32utils
24
22
import bzrlib
25
23
from bzrlib.errors import InvalidURL, InvalidURLJoin
 
24
import bzrlib.urlutils as urlutils
26
25
from bzrlib.tests import TestCaseInTempDir, TestCase, TestSkipped
27
26
 
28
27
 
92
91
        norm_file('uni/%25C2%25B5', u'uni/%C2%B5')
93
92
        norm_file('uni/%20b', u'uni/ b')
94
93
        # All the crazy characters get escaped in local paths => file:/// urls
95
 
        # The ' ' character must not be at the end, because on win32
96
 
        # it gets stripped off by ntpath.abspath
97
 
        norm_file('%27%20%3B/%3F%3A%40%26%3D%2B%24%2C%23', "' ;/?:@&=+$,#")
 
94
        norm_file('%27%3B/%3F%3A%40%26%3D%2B%24%2C%23%20', "';/?:@&=+$,# ")
98
95
 
99
96
    def test_normalize_url_hybrid(self):
100
97
        # Anything with a scheme:// should be treated as a hybrid url
115
112
        eq('http://host/ab/%C2%B5/%C2%B5',
116
113
            normalize_url(u'http://host/ab/%C2%B5/\xb5'))
117
114
 
118
 
        # Unescape characters that don't need to be escaped
119
 
        eq('http://host/~bob%2525-._',
120
 
                normalize_url('http://host/%7Ebob%2525%2D%2E%5F'))
121
 
        eq('http://host/~bob%2525-._',
122
 
                normalize_url(u'http://host/%7Ebob%2525%2D%2E%5F'))
123
 
 
124
115
        # Normalize verifies URLs when they are not unicode
125
116
        # (indicating they did not come from the user)
126
117
        self.assertRaises(InvalidURL, normalize_url, 'http://host/\xb5')
203
194
            joined = urlutils.join(*args)
204
195
            self.assertEqual(expected, joined)
205
196
 
 
197
        # Test a single element
 
198
        test('foo', 'foo')
 
199
 
206
200
        # Test relative path joining
207
 
        test('foo', 'foo') # relative fragment with nothing is preserved.
208
201
        test('foo/bar', 'foo', 'bar')
209
202
        test('http://foo/bar', 'http://foo', 'bar')
210
203
        test('http://foo/bar', 'http://foo', '.', 'bar')
211
204
        test('http://foo/baz', 'http://foo', 'bar', '../baz')
212
205
        test('http://foo/bar/baz', 'http://foo', 'bar/baz')
213
206
        test('http://foo/baz', 'http://foo', 'bar/../baz')
214
 
        test('http://foo/baz', 'http://foo/bar/', '../baz')
215
207
 
216
208
        # Absolute paths
217
 
        test('http://foo', 'http://foo') # abs url with nothing is preserved.
218
209
        test('http://bar', 'http://foo', 'http://bar')
219
210
        test('sftp://bzr/foo', 'http://foo', 'bar', 'sftp://bzr/foo')
220
211
        test('file:///bar', 'foo', 'file:///bar')
221
 
        test('http://bar/', 'http://foo', 'http://bar/')
222
 
        test('http://bar/a', 'http://foo', 'http://bar/a')
223
 
        test('http://bar/a/', 'http://foo', 'http://bar/a/')
224
 
 
225
 
        # From a base path
226
 
        test('file:///foo', 'file:///', 'foo')
227
 
        test('file:///bar/foo', 'file:///bar/', 'foo')
228
 
        test('http://host/foo', 'http://host/', 'foo')
229
 
        test('http://host/', 'http://host', '')
230
212
        
231
213
        # Invalid joinings
232
214
        # Cannot go above root
233
 
        # Implicitly at root:
234
215
        self.assertRaises(InvalidURLJoin, urlutils.join,
235
216
                'http://foo', '../baz')
236
 
        self.assertRaises(InvalidURLJoin, urlutils.join,
237
 
                'http://foo', '/..')
238
 
        # Joining from a path explicitly under the root.
239
 
        self.assertRaises(InvalidURLJoin, urlutils.join,
240
 
                'http://foo/a', '../../b')
241
 
 
242
 
    def test_joinpath(self):
243
 
        def test(expected, *args):
244
 
            joined = urlutils.joinpath(*args)
245
 
            self.assertEqual(expected, joined)
246
 
 
247
 
        # Test a single element
248
 
        test('foo', 'foo')
249
 
 
250
 
        # Test relative path joining
251
 
        test('foo/bar', 'foo', 'bar')
252
 
        test('foo/bar', 'foo', '.', 'bar')
253
 
        test('foo/baz', 'foo', 'bar', '../baz')
254
 
        test('foo/bar/baz', 'foo', 'bar/baz')
255
 
        test('foo/baz', 'foo', 'bar/../baz')
256
 
 
257
 
        # Test joining to an absolute path
258
 
        test('/foo', '/foo')
259
 
        test('/foo', '/foo', '.')
260
 
        test('/foo/bar', '/foo', 'bar')
261
 
        test('/', '/foo', '..')
262
 
 
263
 
        # Test joining with an absolute path
264
 
        test('/bar', 'foo', '/bar')
265
 
 
266
 
        # Test joining to a path with a trailing slash
267
 
        test('foo/bar', 'foo/', 'bar')
268
 
        
269
 
        # Invalid joinings
270
 
        # Cannot go above root
271
 
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '../baz')
272
 
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '..')
273
 
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '/..')
274
217
 
275
218
    def test_function_type(self):
276
219
        if sys.platform == 'win32':
307
250
        to_url = urlutils._win32_local_path_to_url
308
251
        self.assertEqual('file:///C:/path/to/foo',
309
252
            to_url('C:/path/to/foo'))
310
 
        # BOGUS: on win32, ntpath.abspath will strip trailing
311
 
        #       whitespace, so this will always fail
312
 
        #       Though under linux, it fakes abspath support
313
 
        #       and thus will succeed
314
 
        # self.assertEqual('file:///C:/path/to/foo%20',
315
 
        #     to_url('C:/path/to/foo '))
316
 
        self.assertEqual('file:///C:/path/to/f%20oo',
317
 
            to_url('C:/path/to/f oo'))
318
253
 
319
254
        try:
320
255
            result = to_url(u'd:/path/to/r\xe4ksm\xf6rg\xe5s')
323
258
 
324
259
        self.assertEqual('file:///D:/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
325
260
 
326
 
    def test_win32_unc_path_to_url(self):
327
 
        to_url = urlutils._win32_local_path_to_url
328
 
        self.assertEqual('file://HOST/path',
329
 
            to_url(r'\\HOST\path'))
330
 
        self.assertEqual('file://HOST/path',
331
 
            to_url('//HOST/path'))
332
 
 
333
 
        try:
334
 
            result = to_url(u'//HOST/path/to/r\xe4ksm\xf6rg\xe5s')
335
 
        except UnicodeError:
336
 
            raise TestSkipped("local encoding cannot handle unicode")
337
 
 
338
 
        self.assertEqual('file://HOST/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
339
 
 
340
 
 
341
261
    def test_win32_local_path_from_url(self):
342
262
        from_url = urlutils._win32_local_path_from_url
343
263
        self.assertEqual('C:/path/to/foo',
345
265
        self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
346
266
            from_url('file:///d|/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
347
267
        self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
348
 
            from_url('file:///d:/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
 
268
            from_url('file:///d|/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
349
269
 
350
270
        self.assertRaises(InvalidURL, from_url, '/path/to/foo')
351
271
        # Not a valid _win32 url, no drive letter
352
272
        self.assertRaises(InvalidURL, from_url, 'file:///path/to/foo')
353
273
 
354
 
    def test_win32_unc_path_from_url(self):
355
 
        from_url = urlutils._win32_local_path_from_url
356
 
        self.assertEqual('//HOST/path', from_url('file://HOST/path'))
357
 
        # despite IE allows 2, 4, 5 and 6 slashes in URL to another machine
358
 
        # we want to use only 2 slashes
359
 
        # Firefox understand only 5 slashes in URL, but it's ugly
360
 
        self.assertRaises(InvalidURL, from_url, 'file:////HOST/path')
361
 
        self.assertRaises(InvalidURL, from_url, 'file://///HOST/path')
362
 
        self.assertRaises(InvalidURL, from_url, 'file://////HOST/path')
363
 
        # check for file://C:/ instead of file:///C:/
364
 
        self.assertRaises(InvalidURL, from_url, 'file://C:/path')
365
 
 
366
 
    def test_win32_extract_drive_letter(self):
367
 
        extract = urlutils._win32_extract_drive_letter
368
 
        self.assertEqual(('file:///C:', '/foo'), extract('file://', '/C:/foo'))
369
 
        self.assertEqual(('file:///d|', '/path'), extract('file://', '/d|/path'))
370
 
        self.assertRaises(InvalidURL, extract, 'file://', '/path')
371
 
 
372
274
    def test_split(self):
373
275
        # Test bzrlib.urlutils.split()
374
276
        split = urlutils.split
375
277
        if sys.platform == 'win32':
376
278
            self.assertRaises(InvalidURL, split, 'file:///path/to/foo')
377
279
            self.assertEqual(('file:///C|/', 'foo'), split('file:///C|/foo'))
378
 
            self.assertEqual(('file:///C:/', ''), split('file:///C:/'))
 
280
            self.assertEqual(('file:///C|/', ''), split('file:///C|/'))
379
281
        else:
380
282
            self.assertEqual(('file:///', 'foo'), split('file:///foo'))
381
283
            self.assertEqual(('file:///', ''), split('file:///'))
404
306
        self.assertEqual(('path/..', 'foo'), split('path/../foo'))
405
307
        self.assertEqual(('../path', 'foo'), split('../path/foo'))
406
308
 
407
 
    def test_win32_strip_local_trailing_slash(self):
408
 
        strip = urlutils._win32_strip_local_trailing_slash
409
 
        self.assertEqual('file://', strip('file://'))
410
 
        self.assertEqual('file:///', strip('file:///'))
411
 
        self.assertEqual('file:///C', strip('file:///C'))
412
 
        self.assertEqual('file:///C:', strip('file:///C:'))
413
 
        self.assertEqual('file:///d|', strip('file:///d|'))
414
 
        self.assertEqual('file:///C:/', strip('file:///C:/'))
415
 
        self.assertEqual('file:///C:/a', strip('file:///C:/a/'))
416
 
 
417
309
    def test_strip_trailing_slash(self):
418
310
        sts = urlutils.strip_trailing_slash
419
311
        if sys.platform == 'win32':
420
312
            self.assertEqual('file:///C|/', sts('file:///C|/'))
421
 
            self.assertEqual('file:///C:/foo', sts('file:///C:/foo'))
 
313
            self.assertEqual('file:///C|/foo', sts('file:///C|/foo'))
422
314
            self.assertEqual('file:///C|/foo', sts('file:///C|/foo/'))
423
315
        else:
424
316
            self.assertEqual('file:///', sts('file:///'))
453
345
            disp_url = urlutils.unescape_for_display(url, encoding=encoding)
454
346
            self.assertIsInstance(disp_url, unicode)
455
347
            self.assertEqual(expected, disp_url)
456
 
 
457
348
        test('http://foo', 'http://foo')
458
349
        if sys.platform == 'win32':
459
 
            test('C:/foo/path', 'file:///C|/foo/path')
460
 
            test('C:/foo/path', 'file:///C:/foo/path')
 
350
            test('C:/foo/path', 'file:///C|foo/path')
461
351
        else:
462
352
            test('/foo/path', 'file:///foo/path')
463
353
 
521
411
                    'file:///home/jelmer/branch/2b')
522
412
        test('../../branch/2b', 'sftp://host/home/jelmer/bar/2b',
523
413
                    'sftp://host/home/jelmer/branch/2b')
524
 
        test('../../branch/feature/%2b', 'http://host/home/jelmer/bar/%2b',
525
 
                    'http://host/home/jelmer/branch/feature/%2b')
 
414
        test('../../branch/feature/2b', 'http://host/home/jelmer/bar/2b',
 
415
                    'http://host/home/jelmer/branch/feature/2b')
526
416
        test('../../branch/feature/2b', 'http://host/home/jelmer/bar/2b/', 
527
417
                    'http://host/home/jelmer/branch/feature/2b')
528
418
        # relative_url should preserve a trailing slash
540
430
        test('http://host/', 'http://host', 'http://host/')
541
431
        #test('.', 'http://host/', 'http://host')
542
432
        test('http://host', 'http://host/', 'http://host')
543
 
 
544
 
 
545
 
class TestCwdToURL(TestCaseInTempDir):
546
 
    """Test that local_path_to_url works base on the cwd"""
547
 
 
548
 
    def test_dot(self):
549
 
        # This test will fail if getcwd is not ascii
550
 
        os.mkdir('mytest')
551
 
        os.chdir('mytest')
552
 
 
553
 
        url = urlutils.local_path_to_url('.')
554
 
        self.assertEndsWith(url, '/mytest')
555
 
 
556
 
    def test_non_ascii(self):
557
 
        if win32utils.winver == 'Windows 98':
558
 
            raise TestSkipped('Windows 98 cannot handle unicode filenames')
559
 
 
560
 
        try:
561
 
            os.mkdir(u'dod\xe9')
562
 
        except UnicodeError:
563
 
            raise TestSkipped('cannot create unicode directory')
564
 
 
565
 
        os.chdir(u'dod\xe9')
566
 
 
567
 
        # On Mac OSX this directory is actually: 
568
 
        #   u'/dode\u0301' => '/dode\xcc\x81
569
 
        # but we should normalize it back to 
570
 
        #   u'/dod\xe9' => '/dod\xc3\xa9'
571
 
        url = urlutils.local_path_to_url('.')
572
 
        self.assertEndsWith(url, '/dod%C3%A9')
573
 
 
574
 
 
575
 
class TestDeriveToLocation(TestCase):
576
 
    """Test that the mapping of FROM_LOCATION to TO_LOCATION works."""
577
 
 
578
 
    def test_to_locations_derived_from_paths(self):
579
 
        derive = urlutils.derive_to_location
580
 
        self.assertEqual("bar", derive("bar"))
581
 
        self.assertEqual("bar", derive("../bar"))
582
 
        self.assertEqual("bar", derive("/foo/bar"))
583
 
        self.assertEqual("bar", derive("c:/foo/bar"))
584
 
        self.assertEqual("bar", derive("c:bar"))
585
 
 
586
 
    def test_to_locations_derived_from_urls(self):
587
 
        derive = urlutils.derive_to_location
588
 
        self.assertEqual("bar", derive("http://foo/bar"))
589
 
        self.assertEqual("bar", derive("bzr+ssh://foo/bar"))
590
 
        self.assertEqual("foo-bar", derive("lp:foo-bar"))