~bzr-pqm/bzr/bzr.dev

6614.1.2 by Vincent Ladeuil
Fix assertNotEquals being deprecated by using assertNotEqual.
1
# Copyright (C) 2006-2012, 2015, 2016 Canonical Ltd
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
16
17
"""Tests for the urlutils wrapper."""
18
19
import os
20
import sys
21
2279.4.2 by Alexander Belchenko
Don't do normpath after abspath, because this function is called inside abspath
22
from bzrlib import osutils, urlutils, win32utils
6240.4.2 by Jelmer Vernooij
Moar tests.
23
from bzrlib.errors import (
24
    InvalidURL,
25
    InvalidURLJoin,
26
    InvalidRebaseURLs,
27
    PathNotChild,
28
    )
6603.1.2 by Vincent Ladeuil
Skip the windows tests when not running on windows.
29
from bzrlib.tests import features, TestCaseInTempDir, TestCase, TestSkipped
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
30
31
32
class TestUrlToPath(TestCase):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
33
1685.1.49 by John Arbash Meinel
Added bzrlib.urlutils.split and basename + dirname
34
    def test_basename(self):
35
        # bzrlib.urlutils.basename
36
        # Test bzrlib.urlutils.split()
37
        basename = urlutils.basename
38
        if sys.platform == 'win32':
39
            self.assertRaises(InvalidURL, basename, 'file:///path/to/foo')
40
            self.assertEqual('foo', basename('file:///C|/foo'))
1685.1.78 by Wouter van Heyst
more code cleanup
41
            self.assertEqual('foo', basename('file:///C:/foo'))
42
            self.assertEqual('', basename('file:///C:/'))
1685.1.49 by John Arbash Meinel
Added bzrlib.urlutils.split and basename + dirname
43
        else:
44
            self.assertEqual('foo', basename('file:///foo'))
45
            self.assertEqual('', basename('file:///'))
46
47
        self.assertEqual('foo', basename('http://host/path/to/foo'))
48
        self.assertEqual('foo', basename('http://host/path/to/foo/'))
49
        self.assertEqual('',
50
            basename('http://host/path/to/foo/', exclude_trailing_slash=False))
51
        self.assertEqual('path', basename('http://host/path'))
52
        self.assertEqual('', basename('http://host/'))
53
        self.assertEqual('', basename('http://host'))
54
        self.assertEqual('path', basename('http:///nohost/path'))
55
56
        self.assertEqual('path', basename('random+scheme://user:pass@ahost:port/path'))
57
        self.assertEqual('path', basename('random+scheme://user:pass@ahost:port/path/'))
58
        self.assertEqual('', basename('random+scheme://user:pass@ahost:port/'))
59
60
        # relative paths
61
        self.assertEqual('foo', basename('path/to/foo'))
62
        self.assertEqual('foo', basename('path/to/foo/'))
63
        self.assertEqual('', basename('path/to/foo/',
64
            exclude_trailing_slash=False))
65
        self.assertEqual('foo', basename('path/../foo'))
66
        self.assertEqual('foo', basename('../path/foo'))
67
1685.1.51 by John Arbash Meinel
Working on getting normalize_url working.
68
    def test_normalize_url_files(self):
69
        # Test that local paths are properly normalized
70
        normalize_url = urlutils.normalize_url
71
72
        def norm_file(expected, path):
73
            url = normalize_url(path)
74
            self.assertStartsWith(url, 'file:///')
75
            if sys.platform == 'win32':
76
                url = url[len('file:///C:'):]
77
            else:
78
                url = url[len('file://'):]
79
1685.1.53 by John Arbash Meinel
Updated normalize_url
80
            self.assertEndsWith(url, expected)
1685.1.51 by John Arbash Meinel
Working on getting normalize_url working.
81
82
        norm_file('path/to/foo', 'path/to/foo')
83
        norm_file('/path/to/foo', '/path/to/foo')
84
        norm_file('path/to/foo', '../path/to/foo')
85
86
        # Local paths are assumed to *not* be escaped at all
1685.1.75 by Wouter van Heyst
more tests handle LANG=C
87
        try:
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
88
            u'uni/\xb5'.encode(osutils.get_user_encoding())
1685.1.75 by Wouter van Heyst
more tests handle LANG=C
89
        except UnicodeError:
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
90
            # locale cannot handle unicode
1685.1.75 by Wouter van Heyst
more tests handle LANG=C
91
            pass
92
        else:
93
            norm_file('uni/%C2%B5', u'uni/\xb5')
94
1685.1.51 by John Arbash Meinel
Working on getting normalize_url working.
95
        norm_file('uni/%25C2%25B5', u'uni/%C2%B5')
96
        norm_file('uni/%20b', u'uni/ b')
97
        # All the crazy characters get escaped in local paths => file:/// urls
1711.4.4 by John Arbash Meinel
Fix some broken tests because of stupid ntpath.abspath behavior
98
        # The ' ' character must not be at the end, because on win32
99
        # it gets stripped off by ntpath.abspath
5268.7.4 by Jelmer Vernooij
Only skip escaping , and = when actually necessary.
100
        norm_file('%27%20%3B/%3F%3A%40%26%3D%2B%24%2C%23', "' ;/?:@&=+$,#")
1685.1.51 by John Arbash Meinel
Working on getting normalize_url working.
101
102
    def test_normalize_url_hybrid(self):
103
        # Anything with a scheme:// should be treated as a hybrid url
104
        # which changes what characters get escaped.
105
        normalize_url = urlutils.normalize_url
106
107
        eq = self.assertEqual
108
        eq('file:///foo/', normalize_url(u'file:///foo/'))
109
        eq('file:///foo/%20', normalize_url(u'file:///foo/ '))
110
        eq('file:///foo/%20', normalize_url(u'file:///foo/%20'))
111
        # Don't escape reserved characters
112
        eq('file:///ab_c.d-e/%f:?g&h=i+j;k,L#M$',
113
            normalize_url('file:///ab_c.d-e/%f:?g&h=i+j;k,L#M$'))
114
        eq('http://ab_c.d-e/%f:?g&h=i+j;k,L#M$',
115
            normalize_url('http://ab_c.d-e/%f:?g&h=i+j;k,L#M$'))
116
117
        # Escape unicode characters, but not already escaped chars
118
        eq('http://host/ab/%C2%B5/%C2%B5',
119
            normalize_url(u'http://host/ab/%C2%B5/\xb5'))
120
2208.4.1 by Andrew Bennetts
normalize_url should normalise escaping of unreserved characters, like '~'.
121
        # Unescape characters that don't need to be escaped
122
        eq('http://host/~bob%2525-._',
123
                normalize_url('http://host/%7Ebob%2525%2D%2E%5F'))
124
        eq('http://host/~bob%2525-._',
125
                normalize_url(u'http://host/%7Ebob%2525%2D%2E%5F'))
126
1685.1.51 by John Arbash Meinel
Working on getting normalize_url working.
127
        # Normalize verifies URLs when they are not unicode
128
        # (indicating they did not come from the user)
129
        self.assertRaises(InvalidURL, normalize_url, 'http://host/\xb5')
130
        self.assertRaises(InvalidURL, normalize_url, 'http://host/ ')
1685.1.50 by John Arbash Meinel
Added an re for handling scheme paths.
131
132
    def test_url_scheme_re(self):
133
        # Test paths that may be URLs
134
        def test_one(url, scheme_and_path):
135
            """Assert that _url_scheme_re correctly matches
136
137
            :param scheme_and_path: The (scheme, path) that should be matched
138
                can be None, to indicate it should not match
139
            """
140
            m = urlutils._url_scheme_re.match(url)
141
            if scheme_and_path is None:
142
                self.assertEqual(None, m)
143
            else:
144
                self.assertEqual(scheme_and_path[0], m.group('scheme'))
145
                self.assertEqual(scheme_and_path[1], m.group('path'))
146
147
        # Local paths
148
        test_one('/path', None)
149
        test_one('C:/path', None)
150
        test_one('../path/to/foo', None)
151
        test_one(u'../path/to/fo\xe5', None)
152
153
        # Real URLS
154
        test_one('http://host/path/', ('http', 'host/path/'))
155
        test_one('sftp://host/path/to/foo', ('sftp', 'host/path/to/foo'))
156
        test_one('file:///usr/bin', ('file', '/usr/bin'))
157
        test_one('file:///C:/Windows', ('file', '/C:/Windows'))
158
        test_one('file:///C|/Windows', ('file', '/C|/Windows'))
159
        test_one(u'readonly+sftp://host/path/\xe5', ('readonly+sftp', u'host/path/\xe5'))
160
161
        # Weird stuff
162
        # Can't have slashes or colons in the scheme
163
        test_one('/path/to/://foo', None)
5254.1.5 by Gordon Tyler
Fixes according to spiv's review.
164
        test_one('scheme:stuff://foo', ('scheme', 'stuff://foo'))
1685.1.50 by John Arbash Meinel
Added an re for handling scheme paths.
165
        # Must have more than one character for scheme
166
        test_one('C://foo', None)
167
        test_one('ab://foo', ('ab', 'foo'))
168
1685.1.49 by John Arbash Meinel
Added bzrlib.urlutils.split and basename + dirname
169
    def test_dirname(self):
170
        # Test bzrlib.urlutils.dirname()
171
        dirname = urlutils.dirname
172
        if sys.platform == 'win32':
173
            self.assertRaises(InvalidURL, dirname, 'file:///path/to/foo')
174
            self.assertEqual('file:///C|/', dirname('file:///C|/foo'))
175
            self.assertEqual('file:///C|/', dirname('file:///C|/'))
176
        else:
177
            self.assertEqual('file:///', dirname('file:///foo'))
178
            self.assertEqual('file:///', dirname('file:///'))
179
180
        self.assertEqual('http://host/path/to', dirname('http://host/path/to/foo'))
181
        self.assertEqual('http://host/path/to', dirname('http://host/path/to/foo/'))
182
        self.assertEqual('http://host/path/to/foo',
183
            dirname('http://host/path/to/foo/', exclude_trailing_slash=False))
184
        self.assertEqual('http://host/', dirname('http://host/path'))
185
        self.assertEqual('http://host/', dirname('http://host/'))
186
        self.assertEqual('http://host', dirname('http://host'))
187
        self.assertEqual('http:///nohost', dirname('http:///nohost/path'))
188
189
        self.assertEqual('random+scheme://user:pass@ahost:port/',
190
            dirname('random+scheme://user:pass@ahost:port/path'))
191
        self.assertEqual('random+scheme://user:pass@ahost:port/',
192
            dirname('random+scheme://user:pass@ahost:port/path/'))
193
        self.assertEqual('random+scheme://user:pass@ahost:port/',
194
            dirname('random+scheme://user:pass@ahost:port/'))
195
196
        # relative paths
197
        self.assertEqual('path/to', dirname('path/to/foo'))
198
        self.assertEqual('path/to', dirname('path/to/foo/'))
199
        self.assertEqual('path/to/foo',
200
            dirname('path/to/foo/', exclude_trailing_slash=False))
201
        self.assertEqual('path/..', dirname('path/../foo'))
202
        self.assertEqual('../path', dirname('../path/foo'))
5254.2.1 by Gordon Tyler
Fixed how get_transport's convert_path_to_url tests whether a path is actually a URL.
203
    
204
    def test_is_url(self):
205
        self.assertTrue(urlutils.is_url('http://foo/bar'))
206
        self.assertTrue(urlutils.is_url('bzr+ssh://foo/bar'))
207
        self.assertTrue(urlutils.is_url('lp:foo/bar'))
208
        self.assertTrue(urlutils.is_url('file:///foo/bar'))
209
        self.assertFalse(urlutils.is_url(''))
210
        self.assertFalse(urlutils.is_url('foo'))
211
        self.assertFalse(urlutils.is_url('foo/bar'))
212
        self.assertFalse(urlutils.is_url('/foo'))
213
        self.assertFalse(urlutils.is_url('/foo/bar'))
214
        self.assertFalse(urlutils.is_url('C:/'))
215
        self.assertFalse(urlutils.is_url('C:/foo'))
5254.2.5 by Andrew Bennetts
Revert debugging change accidentally committed by Gordon Tyler.
216
        self.assertFalse(urlutils.is_url('C:/foo/bar'))
1685.1.49 by John Arbash Meinel
Added bzrlib.urlutils.split and basename + dirname
217
1685.1.55 by John Arbash Meinel
Adding bzrlib.urlutils.join() to handle joining URLs
218
    def test_join(self):
219
        def test(expected, *args):
220
            joined = urlutils.join(*args)
221
            self.assertEqual(expected, joined)
222
223
        # Test relative path joining
2018.5.100 by Andrew Bennetts
Fix IndexError in urlutils.join with 'http://host/a' and '../../b'.
224
        test('foo', 'foo') # relative fragment with nothing is preserved.
1685.1.55 by John Arbash Meinel
Adding bzrlib.urlutils.join() to handle joining URLs
225
        test('foo/bar', 'foo', 'bar')
226
        test('http://foo/bar', 'http://foo', 'bar')
227
        test('http://foo/bar', 'http://foo', '.', 'bar')
228
        test('http://foo/baz', 'http://foo', 'bar', '../baz')
229
        test('http://foo/bar/baz', 'http://foo', 'bar/baz')
230
        test('http://foo/baz', 'http://foo', 'bar/../baz')
2018.5.93 by Andrew Bennetts
Fix another bug in urlutils.join.
231
        test('http://foo/baz', 'http://foo/bar/', '../baz')
5254.1.1 by Gordon Tyler
Added support to urlutils for URLs such as Launchpad's lp:foobar.
232
        test('lp:foo/bar', 'lp:foo', 'bar')
233
        test('lp:foo/bar/baz', 'lp:foo', 'bar/baz')
1685.1.55 by John Arbash Meinel
Adding bzrlib.urlutils.join() to handle joining URLs
234
235
        # Absolute paths
2018.5.100 by Andrew Bennetts
Fix IndexError in urlutils.join with 'http://host/a' and '../../b'.
236
        test('http://foo', 'http://foo') # abs url with nothing is preserved.
1685.1.55 by John Arbash Meinel
Adding bzrlib.urlutils.join() to handle joining URLs
237
        test('http://bar', 'http://foo', 'http://bar')
238
        test('sftp://bzr/foo', 'http://foo', 'bar', 'sftp://bzr/foo')
239
        test('file:///bar', 'foo', 'file:///bar')
2018.5.92 by Andrew Bennetts
Small bugfix to urlutils.join: join('anything', 'http://bar/a/') should not strip the trailing slash.
240
        test('http://bar/', 'http://foo', 'http://bar/')
241
        test('http://bar/a', 'http://foo', 'http://bar/a')
242
        test('http://bar/a/', 'http://foo', 'http://bar/a/')
5254.1.1 by Gordon Tyler
Added support to urlutils for URLs such as Launchpad's lp:foobar.
243
        test('lp:bar', 'http://foo', 'lp:bar')
244
        test('lp:bar', 'lp:foo', 'lp:bar')
245
        test('file:///stuff', 'lp:foo', 'file:///stuff')
1711.2.49 by John Arbash Meinel
urlutils.join should work for root paths.
246
247
        # From a base path
248
        test('file:///foo', 'file:///', 'foo')
249
        test('file:///bar/foo', 'file:///bar/', 'foo')
250
        test('http://host/foo', 'http://host/', 'foo')
251
        test('http://host/', 'http://host', '')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
252
1685.1.55 by John Arbash Meinel
Adding bzrlib.urlutils.join() to handle joining URLs
253
        # Invalid joinings
254
        # Cannot go above root
2018.5.100 by Andrew Bennetts
Fix IndexError in urlutils.join with 'http://host/a' and '../../b'.
255
        # Implicitly at root:
1685.1.55 by John Arbash Meinel
Adding bzrlib.urlutils.join() to handle joining URLs
256
        self.assertRaises(InvalidURLJoin, urlutils.join,
257
                'http://foo', '../baz')
2018.5.54 by Andrew Bennetts
Fix ChrootTransportDecorator's abspath method to be consistent with its clone
258
        self.assertRaises(InvalidURLJoin, urlutils.join,
259
                'http://foo', '/..')
2018.5.100 by Andrew Bennetts
Fix IndexError in urlutils.join with 'http://host/a' and '../../b'.
260
        # Joining from a path explicitly under the root.
261
        self.assertRaises(InvalidURLJoin, urlutils.join,
262
                'http://foo/a', '../../b')
2379.1.1 by Robert Collins
urlutils improvements from hpss.
263
2018.5.46 by Andrew Bennetts
Fix ChrootTransportDecorator's clone to pass less surprising offsets to the decorated transport's clone.
264
    def test_joinpath(self):
265
        def test(expected, *args):
266
            joined = urlutils.joinpath(*args)
267
            self.assertEqual(expected, joined)
268
269
        # Test a single element
270
        test('foo', 'foo')
271
272
        # Test relative path joining
273
        test('foo/bar', 'foo', 'bar')
274
        test('foo/bar', 'foo', '.', 'bar')
275
        test('foo/baz', 'foo', 'bar', '../baz')
276
        test('foo/bar/baz', 'foo', 'bar/baz')
277
        test('foo/baz', 'foo', 'bar/../baz')
278
279
        # Test joining to an absolute path
280
        test('/foo', '/foo')
281
        test('/foo', '/foo', '.')
282
        test('/foo/bar', '/foo', 'bar')
283
        test('/', '/foo', '..')
284
285
        # Test joining with an absolute path
286
        test('/bar', 'foo', '/bar')
2018.5.53 by Andrew Bennetts
Small fix to urlutils.joinpath that was causing a misbehaviour in
287
288
        # Test joining to a path with a trailing slash
289
        test('foo/bar', 'foo/', 'bar')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
290
2018.5.46 by Andrew Bennetts
Fix ChrootTransportDecorator's clone to pass less surprising offsets to the decorated transport's clone.
291
        # Invalid joinings
292
        # Cannot go above root
293
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '../baz')
2018.5.54 by Andrew Bennetts
Fix ChrootTransportDecorator's abspath method to be consistent with its clone
294
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '..')
295
        self.assertRaises(InvalidURLJoin, urlutils.joinpath, '/', '/..')
2018.5.46 by Andrew Bennetts
Fix ChrootTransportDecorator's clone to pass less surprising offsets to the decorated transport's clone.
296
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
297
    def test_join_segment_parameters_raw(self):
298
        join_segment_parameters_raw = urlutils.join_segment_parameters_raw
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
299
        self.assertEqual("/somedir/path", 
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
300
            join_segment_parameters_raw("/somedir/path"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
301
        self.assertEqual("/somedir/path,rawdata", 
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
302
            join_segment_parameters_raw("/somedir/path", "rawdata"))
5163.2.2 by Jelmer Vernooij
Add bzrlib.urlutils.join_subsegments.
303
        self.assertRaises(InvalidURLJoin,
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
304
            join_segment_parameters_raw, "/somedir/path",
305
                "rawdata1,rawdata2,rawdata3")
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
306
        self.assertEqual("/somedir/path,bla,bar",
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
307
            join_segment_parameters_raw("/somedir/path", "bla", "bar"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
308
        self.assertEqual("/somedir,exist=some/path,bla,bar",
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
309
            join_segment_parameters_raw("/somedir,exist=some/path",
310
                "bla", "bar"))
5163.2.7 by Jelmer Vernooij
Add type checking.
311
        self.assertRaises(TypeError, join_segment_parameters_raw, 
312
            "/somepath", 42)
5163.2.2 by Jelmer Vernooij
Add bzrlib.urlutils.join_subsegments.
313
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
314
    def test_join_segment_parameters(self):
315
        join_segment_parameters = urlutils.join_segment_parameters
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
316
        self.assertEqual("/somedir/path", 
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
317
            join_segment_parameters("/somedir/path", {}))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
318
        self.assertEqual("/somedir/path,key1=val1", 
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
319
            join_segment_parameters("/somedir/path", {"key1": "val1"}))
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
320
        self.assertRaises(InvalidURLJoin,
321
            join_segment_parameters, "/somedir/path",
322
            {"branch": "brr,brr,brr"})
323
        self.assertRaises(InvalidURLJoin,
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
324
            join_segment_parameters, "/somedir/path", {"key1=val1": "val2"})
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
325
        self.assertEqual("/somedir/path,key1=val1,key2=val2",
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
326
            join_segment_parameters("/somedir/path", {
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
327
                "key1": "val1", "key2": "val2"}))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
328
        self.assertEqual("/somedir/path,key1=val1,key2=val2",
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
329
            join_segment_parameters("/somedir/path,key1=val1", {
330
                "key2": "val2"}))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
331
        self.assertEqual("/somedir/path,key1=val2",
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
332
            join_segment_parameters("/somedir/path,key1=val1", {
333
                "key1": "val2"}))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
334
        self.assertEqual("/somedir,exist=some/path,key1=val1",
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
335
            join_segment_parameters("/somedir,exist=some/path",
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
336
                {"key1": "val1"}))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
337
        self.assertEqual("/,key1=val1,key2=val2",
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
338
            join_segment_parameters("/,key1=val1", {"key2": "val2"}))
5163.2.7 by Jelmer Vernooij
Add type checking.
339
        self.assertRaises(TypeError,
340
            join_segment_parameters, "/,key1=val1", {"foo": 42})
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
341
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
342
    def test_function_type(self):
343
        if sys.platform == 'win32':
5268.7.21 by Jelmer Vernooij
Cope with segment parameters in urls.
344
            self.assertEqual(urlutils._win32_local_path_to_url,
345
                urlutils.local_path_to_url)
346
            self.assertEqual(urlutils._win32_local_path_from_url,
347
                urlutils.local_path_from_url)
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
348
        else:
5268.7.21 by Jelmer Vernooij
Cope with segment parameters in urls.
349
            self.assertEqual(urlutils._posix_local_path_to_url,
350
                urlutils.local_path_to_url)
351
            self.assertEqual(urlutils._posix_local_path_from_url,
352
                urlutils.local_path_from_url)
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
353
354
    def test_posix_local_path_to_url(self):
355
        to_url = urlutils._posix_local_path_to_url
356
        self.assertEqual('file:///path/to/foo',
357
            to_url('/path/to/foo'))
1685.1.75 by Wouter van Heyst
more tests handle LANG=C
358
5268.7.4 by Jelmer Vernooij
Only skip escaping , and = when actually necessary.
359
        self.assertEqual('file:///path/to/foo%2Cbar',
360
            to_url('/path/to/foo,bar'))
361
1685.1.75 by Wouter van Heyst
more tests handle LANG=C
362
        try:
363
            result = to_url(u'/path/to/r\xe4ksm\xf6rg\xe5s')
364
        except UnicodeError:
365
            raise TestSkipped("local encoding cannot handle unicode")
366
367
        self.assertEqual('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
3234.3.1 by Alexander Belchenko
ensure that local_path_to_url() always returns plain string, not unicode.
368
        self.assertFalse(isinstance(result, unicode))
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
369
370
    def test_posix_local_path_from_url(self):
371
        from_url = urlutils._posix_local_path_from_url
372
        self.assertEqual('/path/to/foo',
373
            from_url('file:///path/to/foo'))
5268.7.21 by Jelmer Vernooij
Cope with segment parameters in urls.
374
        self.assertEqual('/path/to/foo',
375
            from_url('file:///path/to/foo,branch=foo'))
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
376
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
377
            from_url('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
378
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
379
            from_url('file:///path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
4828.1.1 by Michael Hudson
test and fix
380
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
381
            from_url('file://localhost/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
382
383
        self.assertRaises(InvalidURL, from_url, '/path/to/foo')
4828.1.1 by Michael Hudson
test and fix
384
        self.assertRaises(
385
            InvalidURL, from_url,
386
            'file://remotehost/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
387
388
    def test_win32_local_path_to_url(self):
389
        to_url = urlutils._win32_local_path_to_url
1711.4.28 by John Arbash Meinel
Update the test suite for Alexander's patch.
390
        self.assertEqual('file:///C:/path/to/foo',
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
391
            to_url('C:/path/to/foo'))
1711.4.4 by John Arbash Meinel
Fix some broken tests because of stupid ntpath.abspath behavior
392
        # BOGUS: on win32, ntpath.abspath will strip trailing
393
        #       whitespace, so this will always fail
394
        #       Though under linux, it fakes abspath support
395
        #       and thus will succeed
396
        # self.assertEqual('file:///C:/path/to/foo%20',
397
        #     to_url('C:/path/to/foo '))
1711.4.28 by John Arbash Meinel
Update the test suite for Alexander's patch.
398
        self.assertEqual('file:///C:/path/to/f%20oo',
1711.4.4 by John Arbash Meinel
Fix some broken tests because of stupid ntpath.abspath behavior
399
            to_url('C:/path/to/f oo'))
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
400
3503.1.2 by adwi2
Permits Windows to serve all paths on all drives.
401
        self.assertEqual('file:///', to_url('/'))
1685.1.75 by Wouter van Heyst
more tests handle LANG=C
402
5268.7.4 by Jelmer Vernooij
Only skip escaping , and = when actually necessary.
403
        self.assertEqual('file:///C:/path/to/foo%2Cbar',
404
            to_url('C:/path/to/foo,bar'))
1685.1.75 by Wouter van Heyst
more tests handle LANG=C
405
        try:
406
            result = to_url(u'd:/path/to/r\xe4ksm\xf6rg\xe5s')
407
        except UnicodeError:
408
            raise TestSkipped("local encoding cannot handle unicode")
409
1711.4.28 by John Arbash Meinel
Update the test suite for Alexander's patch.
410
        self.assertEqual('file:///D:/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
3234.3.1 by Alexander Belchenko
ensure that local_path_to_url() always returns plain string, not unicode.
411
        self.assertFalse(isinstance(result, unicode))
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
412
2162.2.1 by Alexander Belchenko
Testing UNC path conversion
413
    def test_win32_unc_path_to_url(self):
6603.1.2 by Vincent Ladeuil
Skip the windows tests when not running on windows.
414
        self.requireFeature(features.win32_feature)
2162.2.1 by Alexander Belchenko
Testing UNC path conversion
415
        to_url = urlutils._win32_local_path_to_url
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
416
        self.assertEqual('file://HOST/path',
2162.2.1 by Alexander Belchenko
Testing UNC path conversion
417
            to_url(r'\\HOST\path'))
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
418
        self.assertEqual('file://HOST/path',
2162.2.1 by Alexander Belchenko
Testing UNC path conversion
419
            to_url('//HOST/path'))
420
2162.2.5 by Alexander Belchenko
Expand test_win32_unc_path_to_url to check unicode
421
        try:
422
            result = to_url(u'//HOST/path/to/r\xe4ksm\xf6rg\xe5s')
423
        except UnicodeError:
424
            raise TestSkipped("local encoding cannot handle unicode")
425
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
426
        self.assertEqual('file://HOST/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s', result)
3234.3.1 by Alexander Belchenko
ensure that local_path_to_url() always returns plain string, not unicode.
427
        self.assertFalse(isinstance(result, unicode))
2162.2.5 by Alexander Belchenko
Expand test_win32_unc_path_to_url to check unicode
428
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
429
    def test_win32_local_path_from_url(self):
430
        from_url = urlutils._win32_local_path_from_url
1711.4.28 by John Arbash Meinel
Update the test suite for Alexander's patch.
431
        self.assertEqual('C:/path/to/foo',
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
432
            from_url('file:///C|/path/to/foo'))
1711.4.28 by John Arbash Meinel
Update the test suite for Alexander's patch.
433
        self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
434
            from_url('file:///d|/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
1711.4.28 by John Arbash Meinel
Update the test suite for Alexander's patch.
435
        self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
1685.1.79 by Wouter van Heyst
cleanup urlutils
436
            from_url('file:///d:/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
3503.1.2 by adwi2
Permits Windows to serve all paths on all drives.
437
        self.assertEqual('/', from_url('file:///'))
5268.7.21 by Jelmer Vernooij
Cope with segment parameters in urls.
438
        self.assertEqual('C:/path/to/foo',
439
            from_url('file:///C|/path/to/foo,branch=foo'))
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
440
5510.2.3 by Jared Bunting
Changed _win32_local_path_from_url to not allow "file:///C:" form.
441
        self.assertRaises(InvalidURL, from_url, 'file:///C:')
5510.2.1 by Jared Bunting
Modified _win32_local_path_from_url to:
442
        self.assertRaises(InvalidURL, from_url, 'file:///c')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
443
        self.assertRaises(InvalidURL, from_url, '/path/to/foo')
444
        # Not a valid _win32 url, no drive letter
445
        self.assertRaises(InvalidURL, from_url, 'file:///path/to/foo')
446
2162.2.1 by Alexander Belchenko
Testing UNC path conversion
447
    def test_win32_unc_path_from_url(self):
448
        from_url = urlutils._win32_local_path_from_url
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
449
        self.assertEqual('//HOST/path', from_url('file://HOST/path'))
5268.7.21 by Jelmer Vernooij
Cope with segment parameters in urls.
450
        self.assertEqual('//HOST/path',
451
            from_url('file://HOST/path,branch=foo'))
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
452
        # despite IE allows 2, 4, 5 and 6 slashes in URL to another machine
453
        # we want to use only 2 slashes
454
        # Firefox understand only 5 slashes in URL, but it's ugly
2162.2.1 by Alexander Belchenko
Testing UNC path conversion
455
        self.assertRaises(InvalidURL, from_url, 'file:////HOST/path')
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
456
        self.assertRaises(InvalidURL, from_url, 'file://///HOST/path')
2162.2.1 by Alexander Belchenko
Testing UNC path conversion
457
        self.assertRaises(InvalidURL, from_url, 'file://////HOST/path')
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
458
        # check for file://C:/ instead of file:///C:/
459
        self.assertRaises(InvalidURL, from_url, 'file://C:/path')
2162.2.1 by Alexander Belchenko
Testing UNC path conversion
460
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
461
    def test_win32_extract_drive_letter(self):
1711.2.43 by John Arbash Meinel
Split out win32 specific code so that it can be tested on all platforms.
462
        extract = urlutils._win32_extract_drive_letter
463
        self.assertEqual(('file:///C:', '/foo'), extract('file://', '/C:/foo'))
464
        self.assertEqual(('file:///d|', '/path'), extract('file://', '/d|/path'))
465
        self.assertRaises(InvalidURL, extract, 'file://', '/path')
6123.3.1 by Martin
More comprehensive testing for urlutils._win32_extract_drive_letter
466
        # Root drives without slash treated as invalid, see bug #841322
467
        self.assertEqual(('file:///C:', '/'), extract('file://', '/C:/'))
468
        self.assertRaises(InvalidURL, extract, 'file://', '/C:')
469
        # Invalid without drive separator or following forward slash
470
        self.assertRaises(InvalidURL, extract, 'file://', '/C')
471
        self.assertRaises(InvalidURL, extract, 'file://', '/C:ool')
1711.2.43 by John Arbash Meinel
Split out win32 specific code so that it can be tested on all platforms.
472
1685.1.49 by John Arbash Meinel
Added bzrlib.urlutils.split and basename + dirname
473
    def test_split(self):
474
        # Test bzrlib.urlutils.split()
475
        split = urlutils.split
476
        if sys.platform == 'win32':
477
            self.assertRaises(InvalidURL, split, 'file:///path/to/foo')
478
            self.assertEqual(('file:///C|/', 'foo'), split('file:///C|/foo'))
1685.1.79 by Wouter van Heyst
cleanup urlutils
479
            self.assertEqual(('file:///C:/', ''), split('file:///C:/'))
1685.1.49 by John Arbash Meinel
Added bzrlib.urlutils.split and basename + dirname
480
        else:
481
            self.assertEqual(('file:///', 'foo'), split('file:///foo'))
482
            self.assertEqual(('file:///', ''), split('file:///'))
483
484
        self.assertEqual(('http://host/path/to', 'foo'), split('http://host/path/to/foo'))
485
        self.assertEqual(('http://host/path/to', 'foo'), split('http://host/path/to/foo/'))
486
        self.assertEqual(('http://host/path/to/foo', ''),
487
            split('http://host/path/to/foo/', exclude_trailing_slash=False))
488
        self.assertEqual(('http://host/', 'path'), split('http://host/path'))
489
        self.assertEqual(('http://host/', ''), split('http://host/'))
490
        self.assertEqual(('http://host', ''), split('http://host'))
491
        self.assertEqual(('http:///nohost', 'path'), split('http:///nohost/path'))
492
493
        self.assertEqual(('random+scheme://user:pass@ahost:port/', 'path'),
494
            split('random+scheme://user:pass@ahost:port/path'))
495
        self.assertEqual(('random+scheme://user:pass@ahost:port/', 'path'),
496
            split('random+scheme://user:pass@ahost:port/path/'))
497
        self.assertEqual(('random+scheme://user:pass@ahost:port/', ''),
498
            split('random+scheme://user:pass@ahost:port/'))
499
500
        # relative paths
501
        self.assertEqual(('path/to', 'foo'), split('path/to/foo'))
502
        self.assertEqual(('path/to', 'foo'), split('path/to/foo/'))
503
        self.assertEqual(('path/to/foo', ''),
504
            split('path/to/foo/', exclude_trailing_slash=False))
505
        self.assertEqual(('path/..', 'foo'), split('path/../foo'))
506
        self.assertEqual(('../path', 'foo'), split('../path/foo'))
507
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
508
    def test_split_segment_parameters_raw(self):
509
        split_segment_parameters_raw = urlutils.split_segment_parameters_raw
6278.1.2 by Martin Packman
Comment which checks tests for split_segment_parameters are actually doing currently
510
        # Check relative references with absolute paths
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
511
        self.assertEqual(("/some/path", []),
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
512
            split_segment_parameters_raw("/some/path"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
513
        self.assertEqual(("/some/path", ["tip"]),
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
514
            split_segment_parameters_raw("/some/path,tip"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
515
        self.assertEqual(("/some,dir/path", ["tip"]),
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
516
            split_segment_parameters_raw("/some,dir/path,tip"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
517
        self.assertEqual(("/somedir/path", ["heads%2Ftip"]),
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
518
            split_segment_parameters_raw("/somedir/path,heads%2Ftip"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
519
        self.assertEqual(("/somedir/path", ["heads%2Ftip", "bar"]),
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
520
            split_segment_parameters_raw("/somedir/path,heads%2Ftip,bar"))
6278.1.2 by Martin Packman
Comment which checks tests for split_segment_parameters are actually doing currently
521
        # Check relative references with relative paths
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
522
        self.assertEqual(("", ["key1=val1"]),
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
523
            split_segment_parameters_raw(",key1=val1"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
524
        self.assertEqual(("foo/", ["key1=val1"]),
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
525
            split_segment_parameters_raw("foo/,key1=val1"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
526
        self.assertEqual(("foo", ["key1=val1"]),
5268.7.21 by Jelmer Vernooij
Cope with segment parameters in urls.
527
            split_segment_parameters_raw("foo,key1=val1"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
528
        self.assertEqual(("foo/base,la=bla/other/elements", []),
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
529
            split_segment_parameters_raw("foo/base,la=bla/other/elements"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
530
        self.assertEqual(("foo/base,la=bla/other/elements", ["a=b"]),
5163.2.5 by Jelmer Vernooij
rename {split,join}_subsegments -> {split,join}_segment_parameters_raw and add more tests.
531
            split_segment_parameters_raw("foo/base,la=bla/other/elements,a=b"))
6278.1.2 by Martin Packman
Comment which checks tests for split_segment_parameters are actually doing currently
532
        # TODO: Check full URLs as well as relative references
5163.2.1 by Jelmer Vernooij
Add urlutils.split_subsegments.
533
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
534
    def test_split_segment_parameters(self):
535
        split_segment_parameters = urlutils.split_segment_parameters
6278.1.2 by Martin Packman
Comment which checks tests for split_segment_parameters are actually doing currently
536
        # Check relative references with absolute paths
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
537
        self.assertEqual(("/some/path", {}),
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
538
            split_segment_parameters("/some/path"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
539
        self.assertEqual(("/some/path", {"branch": "tip"}),
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
540
            split_segment_parameters("/some/path,branch=tip"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
541
        self.assertEqual(("/some,dir/path", {"branch": "tip"}),
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
542
            split_segment_parameters("/some,dir/path,branch=tip"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
543
        self.assertEqual(("/somedir/path", {"ref": "heads%2Ftip"}),
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
544
            split_segment_parameters("/somedir/path,ref=heads%2Ftip"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
545
        self.assertEqual(("/somedir/path",
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
546
            {"ref": "heads%2Ftip", "key1": "val1"}),
547
            split_segment_parameters(
548
                "/somedir/path,ref=heads%2Ftip,key1=val1"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
549
        self.assertEqual(("/somedir/path", {"ref": "heads%2F=tip"}),
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
550
            split_segment_parameters("/somedir/path,ref=heads%2F=tip"))
6278.1.2 by Martin Packman
Comment which checks tests for split_segment_parameters are actually doing currently
551
        # Check relative references with relative paths
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
552
        self.assertEqual(("", {"key1": "val1"}),
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
553
            split_segment_parameters(",key1=val1"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
554
        self.assertEqual(("foo/", {"key1": "val1"}),
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
555
            split_segment_parameters("foo/,key1=val1"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
556
        self.assertEqual(("foo/base,key1=val1/other/elements", {}),
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
557
            split_segment_parameters("foo/base,key1=val1/other/elements"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
558
        self.assertEqual(("foo/base,key1=val1/other/elements",
5163.2.6 by Jelmer Vernooij
Fix example names in tests.
559
            {"key2": "val2"}), split_segment_parameters(
560
                "foo/base,key1=val1/other/elements,key2=val2"))
6278.1.2 by Martin Packman
Comment which checks tests for split_segment_parameters are actually doing currently
561
        # TODO: Check full URLs as well as relative references
5163.2.3 by Jelmer Vernooij
Add join_segment_parameters / split_segment_parameters.
562
2162.2.6 by Alexander Belchenko
Change tests for win32 UNC path to new file://HOST/path scheme
563
    def test_win32_strip_local_trailing_slash(self):
1711.2.44 by John Arbash Meinel
Factor out another win32 special case and add platform independent tests for it.
564
        strip = urlutils._win32_strip_local_trailing_slash
565
        self.assertEqual('file://', strip('file://'))
566
        self.assertEqual('file:///', strip('file:///'))
567
        self.assertEqual('file:///C', strip('file:///C'))
568
        self.assertEqual('file:///C:', strip('file:///C:'))
569
        self.assertEqual('file:///d|', strip('file:///d|'))
570
        self.assertEqual('file:///C:/', strip('file:///C:/'))
571
        self.assertEqual('file:///C:/a', strip('file:///C:/a/'))
572
1685.1.48 by John Arbash Meinel
Updated strip_trailing_slash to support lots more url stuff, added tests
573
    def test_strip_trailing_slash(self):
574
        sts = urlutils.strip_trailing_slash
575
        if sys.platform == 'win32':
576
            self.assertEqual('file:///C|/', sts('file:///C|/'))
1685.1.79 by Wouter van Heyst
cleanup urlutils
577
            self.assertEqual('file:///C:/foo', sts('file:///C:/foo'))
1685.1.48 by John Arbash Meinel
Updated strip_trailing_slash to support lots more url stuff, added tests
578
            self.assertEqual('file:///C|/foo', sts('file:///C|/foo/'))
579
        else:
580
            self.assertEqual('file:///', sts('file:///'))
581
            self.assertEqual('file:///foo', sts('file:///foo'))
582
            self.assertEqual('file:///foo', sts('file:///foo/'))
583
584
        self.assertEqual('http://host/', sts('http://host/'))
585
        self.assertEqual('http://host/foo', sts('http://host/foo'))
586
        self.assertEqual('http://host/foo', sts('http://host/foo/'))
587
588
        # No need to fail just because the slash is missing
589
        self.assertEqual('http://host', sts('http://host'))
590
        # TODO: jam 20060502 Should this raise InvalidURL?
591
        self.assertEqual('file://', sts('file://'))
592
593
        self.assertEqual('random+scheme://user:pass@ahost:port/path',
594
            sts('random+scheme://user:pass@ahost:port/path'))
595
        self.assertEqual('random+scheme://user:pass@ahost:port/path',
596
            sts('random+scheme://user:pass@ahost:port/path/'))
597
        self.assertEqual('random+scheme://user:pass@ahost:port/',
598
            sts('random+scheme://user:pass@ahost:port/'))
599
600
        # Make sure relative paths work too
601
        self.assertEqual('path/to/foo', sts('path/to/foo'))
602
        self.assertEqual('path/to/foo', sts('path/to/foo/'))
603
        self.assertEqual('../to/foo', sts('../to/foo/'))
604
        self.assertEqual('path/../foo', sts('path/../foo/'))
605
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
606
    def test_unescape_for_display_utf8(self):
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
607
        # Test that URLs are converted to nice unicode strings for display
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
608
        def test(expected, url, encoding='utf-8'):
609
            disp_url = urlutils.unescape_for_display(url, encoding=encoding)
1685.1.58 by Martin Pool
urlutils.unescape_for_display should return Unicode
610
            self.assertIsInstance(disp_url, unicode)
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
611
            self.assertEqual(expected, disp_url)
1685.1.79 by Wouter van Heyst
cleanup urlutils
612
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
613
        test('http://foo', 'http://foo')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
614
        if sys.platform == 'win32':
1711.7.13 by John Arbash Meinel
Fix expected value for urlutils tests
615
            test('C:/foo/path', 'file:///C|/foo/path')
616
            test('C:/foo/path', 'file:///C:/foo/path')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
617
        else:
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
618
            test('/foo/path', 'file:///foo/path')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
619
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
620
        test('http://foo/%2Fbaz', 'http://foo/%2Fbaz')
1685.1.58 by Martin Pool
urlutils.unescape_for_display should return Unicode
621
        test(u'http://host/r\xe4ksm\xf6rg\xe5s',
622
             'http://host/r%C3%A4ksm%C3%B6rg%C3%A5s')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
623
624
        # Make sure special escaped characters stay escaped
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
625
        test(u'http://host/%3B%2F%3F%3A%40%26%3D%2B%24%2C%23',
1685.1.58 by Martin Pool
urlutils.unescape_for_display should return Unicode
626
             'http://host/%3B%2F%3F%3A%40%26%3D%2B%24%2C%23')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
627
628
        # Can we handle sections that don't have utf-8 encoding?
1685.1.58 by Martin Pool
urlutils.unescape_for_display should return Unicode
629
        test(u'http://host/%EE%EE%EE/r\xe4ksm\xf6rg\xe5s',
630
             'http://host/%EE%EE%EE/r%C3%A4ksm%C3%B6rg%C3%A5s')
1685.1.54 by John Arbash Meinel
url_for_display now makes sure output can be properly encoded.
631
632
        # Test encoding into output that can handle some characters
1685.1.58 by Martin Pool
urlutils.unescape_for_display should return Unicode
633
        test(u'http://host/%EE%EE%EE/r\xe4ksm\xf6rg\xe5s',
634
             'http://host/%EE%EE%EE/r%C3%A4ksm%C3%B6rg%C3%A5s',
635
             encoding='iso-8859-1')
636
637
        # This one can be encoded into utf8
638
        test(u'http://host/\u062c\u0648\u062c\u0648',
639
             'http://host/%d8%ac%d9%88%d8%ac%d9%88',
640
             encoding='utf-8')
641
642
        # This can't be put into 8859-1 and so stays as escapes
643
        test(u'http://host/%d8%ac%d9%88%d8%ac%d9%88',
644
             'http://host/%d8%ac%d9%88%d8%ac%d9%88',
645
             encoding='iso-8859-1')
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
646
647
    def test_escape(self):
648
        self.assertEqual('%25', urlutils.escape('%'))
649
        self.assertEqual('%C3%A5', urlutils.escape(u'\xe5'))
3234.3.1 by Alexander Belchenko
ensure that local_path_to_url() always returns plain string, not unicode.
650
        self.assertFalse(isinstance(urlutils.escape(u'\xe5'), unicode))
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
651
4098.3.1 by Jonathan Lange
Don't escape tildes
652
    def test_escape_tildes(self):
653
        self.assertEqual('~foo', urlutils.escape('~foo'))
654
1685.1.45 by John Arbash Meinel
Moved url functions into bzrlib.urlutils
655
    def test_unescape(self):
656
        self.assertEqual('%', urlutils.unescape('%25'))
657
        self.assertEqual(u'\xe5', urlutils.unescape('%C3%A5'))
658
659
        self.assertRaises(InvalidURL, urlutils.unescape, u'\xe5')
660
        self.assertRaises(InvalidURL, urlutils.unescape, '\xe5')
661
        self.assertRaises(InvalidURL, urlutils.unescape, '%E5')
662
663
    def test_escape_unescape(self):
664
        self.assertEqual(u'\xe5', urlutils.unescape(urlutils.escape(u'\xe5')))
665
        self.assertEqual('%', urlutils.unescape(urlutils.escape('%')))
666
1685.1.70 by Wouter van Heyst
working on get_parent, set_parent and relative urls, broken
667
    def test_relative_url(self):
668
        def test(expected, base, other):
669
            result = urlutils.relative_url(base, other)
670
            self.assertEqual(expected, result)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
671
1685.1.70 by Wouter van Heyst
working on get_parent, set_parent and relative urls, broken
672
        test('a', 'http://host/', 'http://host/a')
1685.1.71 by Wouter van Heyst
change branch.{get,set}_parent to store a relative path but return full urls
673
        test('http://entirely/different', 'sftp://host/branch',
674
                    'http://entirely/different')
675
        test('../person/feature', 'http://host/branch/mainline',
676
                    'http://host/branch/person/feature')
1685.1.70 by Wouter van Heyst
working on get_parent, set_parent and relative urls, broken
677
        test('..', 'http://host/branch', 'http://host/')
678
        test('http://host2/branch', 'http://host1/branch', 'http://host2/branch')
1685.1.71 by Wouter van Heyst
change branch.{get,set}_parent to store a relative path but return full urls
679
        test('.', 'http://host1/branch', 'http://host1/branch')
680
        test('../../../branch/2b', 'file:///home/jelmer/foo/bar/2b',
681
                    'file:///home/jelmer/branch/2b')
682
        test('../../branch/2b', 'sftp://host/home/jelmer/bar/2b',
683
                    'sftp://host/home/jelmer/branch/2b')
1685.1.79 by Wouter van Heyst
cleanup urlutils
684
        test('../../branch/feature/%2b', 'http://host/home/jelmer/bar/%2b',
685
                    'http://host/home/jelmer/branch/feature/%2b')
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
686
        test('../../branch/feature/2b', 'http://host/home/jelmer/bar/2b/',
1685.1.71 by Wouter van Heyst
change branch.{get,set}_parent to store a relative path but return full urls
687
                    'http://host/home/jelmer/branch/feature/2b')
688
        # relative_url should preserve a trailing slash
689
        test('../../branch/feature/2b/', 'http://host/home/jelmer/bar/2b/',
690
                    'http://host/home/jelmer/branch/feature/2b/')
691
        test('../../branch/feature/2b/', 'http://host/home/jelmer/bar/2b',
692
                    'http://host/home/jelmer/branch/feature/2b/')
693
694
        # TODO: treat http://host as http://host/
695
        #       relative_url is typically called from a branch.base or
696
        #       transport.base which always ends with a /
697
        #test('a', 'http://host', 'http://host/a')
698
        test('http://host/a', 'http://host', 'http://host/a')
699
        #test('.', 'http://host', 'http://host/')
700
        test('http://host/', 'http://host', 'http://host/')
701
        #test('.', 'http://host/', 'http://host')
702
        test('http://host', 'http://host/', 'http://host')
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
703
3139.2.1 by Alexander Belchenko
bugfix #90847: fix problem with parent location on another logical drive
704
        # On Windows file:///C:/path/to and file:///D:/other/path
705
        # should not use relative url over the non-existent '/' directory.
706
        if sys.platform == 'win32':
707
            # on the same drive
708
            test('../../other/path',
709
                'file:///C:/path/to', 'file:///C:/other/path')
710
            #~next two tests is failed, i.e. urlutils.relative_url expects
711
            #~to see normalized file URLs?
712
            #~test('../../other/path',
713
            #~    'file:///C:/path/to', 'file:///c:/other/path')
714
            #~test('../../other/path',
715
            #~    'file:///C:/path/to', 'file:///C|/other/path')
716
717
            # check UNC paths too
718
            test('../../other/path',
719
                'file://HOST/base/path/to', 'file://HOST/base/other/path')
720
            # on different drives
721
            test('file:///D:/other/path',
722
                'file:///C:/path/to', 'file:///D:/other/path')
723
            # TODO: strictly saying in UNC path //HOST/base is full analog
724
            # of drive letter for hard disk, and this situation is also
725
            # should be exception from rules. [bialix 20071221]
726
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
727
728
class TestCwdToURL(TestCaseInTempDir):
6423.1.1 by Vincent Ladeuil
Cleanup old blackbox tests and then some. Remove os.chdir() calls, caught a few bugs, make sure we don't leave file handles opened.
729
    """Test that local_path_to_url works based on the cwd"""
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
730
731
    def test_dot(self):
732
        # This test will fail if getcwd is not ascii
1830.3.17 by John Arbash Meinel
list_files() with wrong normalized_filename code raises exceptions. Fix this
733
        os.mkdir('mytest')
734
        os.chdir('mytest')
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
735
736
        url = urlutils.local_path_to_url('.')
1830.3.17 by John Arbash Meinel
list_files() with wrong normalized_filename code raises exceptions. Fix this
737
        self.assertEndsWith(url, '/mytest')
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
738
739
    def test_non_ascii(self):
2279.4.2 by Alexander Belchenko
Don't do normpath after abspath, because this function is called inside abspath
740
        if win32utils.winver == 'Windows 98':
741
            raise TestSkipped('Windows 98 cannot handle unicode filenames')
742
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
743
        try:
744
            os.mkdir(u'dod\xe9')
745
        except UnicodeError:
746
            raise TestSkipped('cannot create unicode directory')
747
748
        os.chdir(u'dod\xe9')
749
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
750
        # On Mac OSX this directory is actually:
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
751
        #   u'/dode\u0301' => '/dode\xcc\x81
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
752
        # but we should normalize it back to
1830.3.13 by John Arbash Meinel
Add a test that urlutils creates normalized paths
753
        #   u'/dod\xe9' => '/dod\xc3\xa9'
754
        url = urlutils.local_path_to_url('.')
755
        self.assertEndsWith(url, '/dod%C3%A9')
2512.4.1 by Ian Clatworthy
Fixes #115491 - 'branch lp:projname' now creates ./projname as exected
756
757
758
class TestDeriveToLocation(TestCase):
759
    """Test that the mapping of FROM_LOCATION to TO_LOCATION works."""
760
761
    def test_to_locations_derived_from_paths(self):
762
        derive = urlutils.derive_to_location
763
        self.assertEqual("bar", derive("bar"))
764
        self.assertEqual("bar", derive("../bar"))
765
        self.assertEqual("bar", derive("/foo/bar"))
766
        self.assertEqual("bar", derive("c:/foo/bar"))
767
        self.assertEqual("bar", derive("c:bar"))
768
769
    def test_to_locations_derived_from_urls(self):
770
        derive = urlutils.derive_to_location
771
        self.assertEqual("bar", derive("http://foo/bar"))
772
        self.assertEqual("bar", derive("bzr+ssh://foo/bar"))
773
        self.assertEqual("foo-bar", derive("lp:foo-bar"))
3242.3.26 by Aaron Bentley
Implement rebase_url
774
775
776
class TestRebaseURL(TestCase):
777
    """Test the behavior of rebase_url."""
778
779
    def test_non_relative(self):
780
        result = urlutils.rebase_url('file://foo', 'file://foo',
781
                                     'file://foo/bar')
782
        self.assertEqual('file://foo', result)
783
        result = urlutils.rebase_url('/foo', 'file://foo',
784
                                     'file://foo/bar')
785
        self.assertEqual('/foo', result)
786
3242.3.36 by Aaron Bentley
Updates from review comments
787
    def test_different_ports(self):
788
        e = self.assertRaises(InvalidRebaseURLs, urlutils.rebase_url,
789
                              'foo', 'http://bar:80', 'http://bar:81')
790
        self.assertEqual(str(e), "URLs differ by more than path:"
791
                         " 'http://bar:80' and 'http://bar:81'")
792
793
    def test_different_hosts(self):
3242.3.33 by Aaron Bentley
Handle relative URL stacking cleanly
794
        e = self.assertRaises(InvalidRebaseURLs, urlutils.rebase_url,
795
                              'foo', 'http://bar', 'http://baz')
796
        self.assertEqual(str(e), "URLs differ by more than path: 'http://bar'"
797
                         " and 'http://baz'")
3242.3.26 by Aaron Bentley
Implement rebase_url
798
3242.3.36 by Aaron Bentley
Updates from review comments
799
    def test_different_protocol(self):
800
        e = self.assertRaises(InvalidRebaseURLs, urlutils.rebase_url,
801
                              'foo', 'http://bar', 'ftp://bar')
802
        self.assertEqual(str(e), "URLs differ by more than path: 'http://bar'"
803
                         " and 'ftp://bar'")
804
3242.3.26 by Aaron Bentley
Implement rebase_url
805
    def test_rebase_success(self):
806
        self.assertEqual('../bar', urlutils.rebase_url('bar', 'http://baz/',
807
                         'http://baz/qux'))
808
        self.assertEqual('qux/bar', urlutils.rebase_url('bar',
809
                         'http://baz/qux', 'http://baz/'))
810
        self.assertEqual('.', urlutils.rebase_url('foo',
811
                         'http://bar/', 'http://bar/foo/'))
3567.2.1 by Michael Hudson
urlutils.rebase_url handles '..' path segments in 'url'
812
        self.assertEqual('qux/bar', urlutils.rebase_url('../bar',
813
                         'http://baz/qux/foo', 'http://baz/'))
3242.3.26 by Aaron Bentley
Implement rebase_url
814
815
    def test_determine_relative_path(self):
816
        self.assertEqual('../../baz/bar',
817
                         urlutils.determine_relative_path(
818
                         '/qux/quxx', '/baz/bar'))
819
        self.assertEqual('..',
820
                         urlutils.determine_relative_path(
821
                         '/bar/baz', '/bar'))
822
        self.assertEqual('baz',
823
                         urlutils.determine_relative_path(
824
                         '/bar', '/bar/baz'))
825
        self.assertEqual('.', urlutils.determine_relative_path(
826
                         '/bar', '/bar'))
3873.3.1 by Martin Pool
Move Transport._split_url to urlutils, and ad a simple test
827
828
829
class TestParseURL(TestCase):
830
6055.2.1 by Jelmer Vernooij
Add UnparsedUrl.
831
    def test_parse_simple(self):
832
        parsed = urlutils.parse_url('http://example.com:80/one')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
833
        self.assertEqual(('http', None, None, 'example.com', 80, '/one'),
6055.2.6 by Jelmer Vernooij
Split out parse_url.
834
            parsed)
6055.2.1 by Jelmer Vernooij
Add UnparsedUrl.
835
836
    def test_ipv6(self):
837
        parsed = urlutils.parse_url('http://[1:2:3::40]/one')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
838
        self.assertEqual(('http', None, None, '1:2:3::40', None, '/one'),
6055.2.6 by Jelmer Vernooij
Split out parse_url.
839
            parsed)
6055.2.1 by Jelmer Vernooij
Add UnparsedUrl.
840
841
    def test_ipv6_port(self):
842
        parsed = urlutils.parse_url('http://[1:2:3::40]:80/one')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
843
        self.assertEqual(('http', None, None, '1:2:3::40', 80, '/one'),
6055.2.6 by Jelmer Vernooij
Split out parse_url.
844
            parsed)
6055.2.7 by Jelmer Vernooij
Change parse_url to URL.from_string.
845
846
847
class TestURL(TestCase):
848
849
    def test_parse_simple(self):
850
        parsed = urlutils.URL.from_string('http://example.com:80/one')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
851
        self.assertEqual('http', parsed.scheme)
6055.2.7 by Jelmer Vernooij
Change parse_url to URL.from_string.
852
        self.assertIs(None, parsed.user)
853
        self.assertIs(None, parsed.password)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
854
        self.assertEqual('example.com', parsed.host)
855
        self.assertEqual(80, parsed.port)
856
        self.assertEqual('/one', parsed.path)
6055.2.7 by Jelmer Vernooij
Change parse_url to URL.from_string.
857
858
    def test_ipv6(self):
859
        parsed = urlutils.URL.from_string('http://[1:2:3::40]/one')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
860
        self.assertEqual('http', parsed.scheme)
6055.2.7 by Jelmer Vernooij
Change parse_url to URL.from_string.
861
        self.assertIs(None, parsed.port)
862
        self.assertIs(None, parsed.user)
863
        self.assertIs(None, parsed.password)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
864
        self.assertEqual('1:2:3::40', parsed.host)
865
        self.assertEqual('/one', parsed.path)
6055.2.7 by Jelmer Vernooij
Change parse_url to URL.from_string.
866
867
    def test_ipv6_port(self):
868
        parsed = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
869
        self.assertEqual('http', parsed.scheme)
870
        self.assertEqual('1:2:3::40', parsed.host)
6055.2.7 by Jelmer Vernooij
Change parse_url to URL.from_string.
871
        self.assertIs(None, parsed.user)
872
        self.assertIs(None, parsed.password)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
873
        self.assertEqual(80, parsed.port)
874
        self.assertEqual('/one', parsed.path)
6055.2.7 by Jelmer Vernooij
Change parse_url to URL.from_string.
875
876
    def test_quoted(self):
877
        parsed = urlutils.URL.from_string(
878
            'http://ro%62ey:h%40t@ex%41mple.com:2222/path')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
879
        self.assertEqual(parsed.quoted_host, 'ex%41mple.com')
880
        self.assertEqual(parsed.host, 'exAmple.com')
881
        self.assertEqual(parsed.port, 2222)
882
        self.assertEqual(parsed.quoted_user, 'ro%62ey')
883
        self.assertEqual(parsed.user, 'robey')
884
        self.assertEqual(parsed.quoted_password, 'h%40t')
885
        self.assertEqual(parsed.password, 'h@t')
886
        self.assertEqual(parsed.path, '/path')
6055.2.8 by Jelmer Vernooij
Add repr()
887
888
    def test_eq(self):
889
        parsed1 = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
890
        parsed2 = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
891
        self.assertEqual(parsed1, parsed2)
892
        self.assertEqual(parsed1, parsed1)
6055.2.8 by Jelmer Vernooij
Add repr()
893
        parsed2.path = '/two'
6614.1.2 by Vincent Ladeuil
Fix assertNotEquals being deprecated by using assertNotEqual.
894
        self.assertNotEqual(parsed1, parsed2)
6055.2.8 by Jelmer Vernooij
Add repr()
895
896
    def test_repr(self):
897
        parsed = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
898
        self.assertEqual(
6055.2.11 by Jelmer Vernooij
Fix tests.
899
            "<URL('http', None, None, '1:2:3::40', 80, '/one')>",
6055.2.8 by Jelmer Vernooij
Add repr()
900
            repr(parsed))
901
6055.2.13 by Jelmer Vernooij
Add URL.__str__.
902
    def test_str(self):
903
        parsed = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
904
        self.assertEqual('http://[1:2:3::40]:80/one', str(parsed))
6055.2.13 by Jelmer Vernooij
Add URL.__str__.
905
6055.2.15 by Jelmer Vernooij
Add URL._combine_paths.
906
    def test__combine_paths(self):
907
        combine = urlutils.URL._combine_paths
908
        self.assertEqual('/home/sarah/project/foo',
909
                         combine('/home/sarah', 'project/foo'))
910
        self.assertEqual('/etc',
911
                         combine('/home/sarah', '../../etc'))
912
        self.assertEqual('/etc',
913
                         combine('/home/sarah', '../../../etc'))
914
        self.assertEqual('/etc',
915
                         combine('/home/sarah', '/etc'))
6055.2.17 by Jelmer Vernooij
Add URL.clone().
916
917
    def test_clone(self):
918
        url = urlutils.URL.from_string('http://[1:2:3::40]:80/one')
919
        url1 = url.clone("two")
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
920
        self.assertEqual("/one/two", url1.path)
6055.2.17 by Jelmer Vernooij
Add URL.clone().
921
        url2 = url.clone("/two")
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
922
        self.assertEqual("/two", url2.path)
6055.2.17 by Jelmer Vernooij
Add URL.clone().
923
        url3 = url.clone()
924
        self.assertIsNot(url, url3)
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
925
        self.assertEqual(url, url3)
6240.4.2 by Jelmer Vernooij
Moar tests.
926
927
928
class TestFileRelpath(TestCase):
929
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
930
    # GZ 2011-11-18: A way to override all path handling functions to one
931
    #                platform or another for testing would be nice.
932
933
    def _with_posix_paths(self):
934
        self.overrideAttr(urlutils, "local_path_from_url",
935
            urlutils._posix_local_path_from_url)
936
        self.overrideAttr(urlutils, "MIN_ABS_FILEURL_LENGTH", len("file:///"))
937
        self.overrideAttr(osutils, "normpath", osutils._posix_normpath)
938
        self.overrideAttr(osutils, "abspath", osutils._posix_abspath)
939
        self.overrideAttr(osutils, "normpath", osutils._posix_normpath)
940
        self.overrideAttr(osutils, "pathjoin", osutils.posixpath.join)
941
        self.overrideAttr(osutils, "split", osutils.posixpath.split)
942
        self.overrideAttr(osutils, "MIN_ABS_PATHLENGTH", 1)
943
944
    def _with_win32_paths(self):
945
        self.overrideAttr(urlutils, "local_path_from_url",
946
            urlutils._win32_local_path_from_url)
947
        self.overrideAttr(urlutils, "MIN_ABS_FILEURL_LENGTH",
948
            urlutils.WIN32_MIN_ABS_FILEURL_LENGTH)
949
        self.overrideAttr(osutils, "abspath", osutils._win32_abspath)
950
        self.overrideAttr(osutils, "normpath", osutils._win32_normpath)
951
        self.overrideAttr(osutils, "pathjoin", osutils._win32_pathjoin)
952
        self.overrideAttr(osutils, "split", osutils.ntpath.split)
953
        self.overrideAttr(osutils, "MIN_ABS_PATHLENGTH", 3)
954
955
    def test_same_url_posix(self):
956
        self._with_posix_paths()
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
957
        self.assertEqual("",
6240.4.2 by Jelmer Vernooij
Moar tests.
958
            urlutils.file_relpath("file:///a", "file:///a"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
959
        self.assertEqual("",
6240.4.2 by Jelmer Vernooij
Moar tests.
960
            urlutils.file_relpath("file:///a", "file:///a/"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
961
        self.assertEqual("",
6240.4.2 by Jelmer Vernooij
Moar tests.
962
            urlutils.file_relpath("file:///a/", "file:///a"))
963
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
964
    def test_same_url_win32(self):
965
        self._with_win32_paths()
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
966
        self.assertEqual("",
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
967
            urlutils.file_relpath("file:///A:/", "file:///A:/"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
968
        self.assertEqual("",
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
969
            urlutils.file_relpath("file:///A|/", "file:///A:/"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
970
        self.assertEqual("",
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
971
            urlutils.file_relpath("file:///A:/b/", "file:///A:/b/"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
972
        self.assertEqual("",
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
973
            urlutils.file_relpath("file:///A:/b", "file:///A:/b/"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
974
        self.assertEqual("",
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
975
            urlutils.file_relpath("file:///A:/b/", "file:///A:/b"))
976
977
    def test_child_posix(self):
978
        self._with_posix_paths()
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
979
        self.assertEqual("b",
6240.4.2 by Jelmer Vernooij
Moar tests.
980
            urlutils.file_relpath("file:///a", "file:///a/b"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
981
        self.assertEqual("b",
6240.4.2 by Jelmer Vernooij
Moar tests.
982
            urlutils.file_relpath("file:///a/", "file:///a/b"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
983
        self.assertEqual("b/c",
6240.4.2 by Jelmer Vernooij
Moar tests.
984
            urlutils.file_relpath("file:///a", "file:///a/b/c"))
985
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
986
    def test_child_win32(self):
987
        self._with_win32_paths()
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
988
        self.assertEqual("b",
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
989
            urlutils.file_relpath("file:///A:/", "file:///A:/b"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
990
        self.assertEqual("b",
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
991
            urlutils.file_relpath("file:///A|/", "file:///A:/b"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
992
        self.assertEqual("c",
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
993
            urlutils.file_relpath("file:///A:/b", "file:///A:/b/c"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
994
        self.assertEqual("c",
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
995
            urlutils.file_relpath("file:///A:/b/", "file:///A:/b/c"))
6614.1.3 by Vincent Ladeuil
Fix assertEquals being deprecated by using assertEqual.
996
        self.assertEqual("c/d",
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
997
            urlutils.file_relpath("file:///A:/b", "file:///A:/b/c/d"))
998
999
    def test_sibling_posix(self):
1000
        self._with_posix_paths()
6240.4.2 by Jelmer Vernooij
Moar tests.
1001
        self.assertRaises(PathNotChild,
1002
            urlutils.file_relpath, "file:///a/b", "file:///a/c")
1003
        self.assertRaises(PathNotChild,
1004
            urlutils.file_relpath, "file:///a/b/", "file:///a/c")
1005
        self.assertRaises(PathNotChild,
1006
            urlutils.file_relpath, "file:///a/b/", "file:///a/c/")
1007
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
1008
    def test_sibling_win32(self):
1009
        self._with_win32_paths()
1010
        self.assertRaises(PathNotChild,
1011
            urlutils.file_relpath, "file:///A:/b", "file:///A:/c")
1012
        self.assertRaises(PathNotChild,
1013
            urlutils.file_relpath, "file:///A:/b/", "file:///A:/c")
1014
        self.assertRaises(PathNotChild,
1015
            urlutils.file_relpath, "file:///A:/b/", "file:///A:/c/")
1016
1017
    def test_parent_posix(self):
1018
        self._with_posix_paths()
6240.4.2 by Jelmer Vernooij
Moar tests.
1019
        self.assertRaises(PathNotChild,
1020
            urlutils.file_relpath, "file:///a/b", "file:///a")
1021
        self.assertRaises(PathNotChild,
1022
            urlutils.file_relpath, "file:///a/b", "file:///a/")
6240.4.4 by Martin Packman
Test urlutils.file_relpath against both posix and win32 implementations
1023
1024
    def test_parent_win32(self):
1025
        self._with_win32_paths()
1026
        self.assertRaises(PathNotChild,
1027
            urlutils.file_relpath, "file:///A:/b", "file:///A:/")
1028
        self.assertRaises(PathNotChild,
1029
            urlutils.file_relpath, "file:///A:/b/c", "file:///A:/b")
6379.4.4 by Jelmer Vernooij
Add some tests.
1030
1031
1032
class QuoteTests(TestCase):
1033
1034
    def test_quote(self):
1035
        self.assertEqual('abc%20def', urlutils.quote('abc def'))
1036
        self.assertEqual('abc%2Fdef', urlutils.quote('abc/def', safe=''))
1037
        self.assertEqual('abc/def', urlutils.quote('abc/def', safe='/'))
1038
1039
    def test_quote_tildes(self):
1040
        self.assertEqual('%7Efoo', urlutils.quote('~foo'))
1041
        self.assertEqual('~foo', urlutils.quote('~foo', safe='/~'))
1042
1043
    def test_unquote(self):
1044
        self.assertEqual('%', urlutils.unquote('%25'))
1045
        self.assertEqual('\xc3\xa5', urlutils.unquote('%C3%A5'))
1046
        self.assertEqual(u"\xe5", urlutils.unquote(u'\xe5'))