/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: Jelmer Vernooij
  • Date: 2018-08-14 01:15:02 UTC
  • mto: This revision was merged to the branch mainline in revision 7078.
  • Revision ID: jelmer@jelmer.uk-20180814011502-5zaydaq02vc2qxo1
Fix tests.

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