/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 bzrlib/tests/test_urlutils.py

  • Committer: John Arbash Meinel
  • Date: 2006-05-10 19:59:55 UTC
  • mfrom: (1704 +trunk)
  • mto: This revision was merged to the branch mainline in revision 1752.
  • Revision ID: john@arbash-meinel.com-20060510195955-df080afb1daa3a96
[merge] bzr.dev 1704

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2005 by Canonical Ltd
 
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
 
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
16
 
 
17
"""Tests for the urlutils wrapper."""
 
18
 
 
19
import os
 
20
import sys
 
21
 
 
22
import bzrlib
 
23
from bzrlib.errors import InvalidURL
 
24
import bzrlib.urlutils as urlutils
 
25
from bzrlib.tests import TestCaseInTempDir, TestCase
 
26
 
 
27
 
 
28
class TestUrlToPath(TestCase):
 
29
    
 
30
    def test_basename(self):
 
31
        # bzrlib.urlutils.basename
 
32
        # Test bzrlib.urlutils.split()
 
33
        basename = urlutils.basename
 
34
        if sys.platform == 'win32':
 
35
            self.assertRaises(InvalidURL, basename, 'file:///path/to/foo')
 
36
            self.assertEqual('foo', basename('file:///C|/foo'))
 
37
            self.assertEqual('', basename('file:///C|/'))
 
38
        else:
 
39
            self.assertEqual('foo', basename('file:///foo'))
 
40
            self.assertEqual('', basename('file:///'))
 
41
 
 
42
        self.assertEqual('foo', basename('http://host/path/to/foo'))
 
43
        self.assertEqual('foo', basename('http://host/path/to/foo/'))
 
44
        self.assertEqual('',
 
45
            basename('http://host/path/to/foo/', exclude_trailing_slash=False))
 
46
        self.assertEqual('path', basename('http://host/path'))
 
47
        self.assertEqual('', basename('http://host/'))
 
48
        self.assertEqual('', basename('http://host'))
 
49
        self.assertEqual('path', basename('http:///nohost/path'))
 
50
 
 
51
        self.assertEqual('path', basename('random+scheme://user:pass@ahost:port/path'))
 
52
        self.assertEqual('path', basename('random+scheme://user:pass@ahost:port/path/'))
 
53
        self.assertEqual('', basename('random+scheme://user:pass@ahost:port/'))
 
54
 
 
55
        # relative paths
 
56
        self.assertEqual('foo', basename('path/to/foo'))
 
57
        self.assertEqual('foo', basename('path/to/foo/'))
 
58
        self.assertEqual('', basename('path/to/foo/',
 
59
            exclude_trailing_slash=False))
 
60
        self.assertEqual('foo', basename('path/../foo'))
 
61
        self.assertEqual('foo', basename('../path/foo'))
 
62
 
 
63
    def test_normalize_url_files(self):
 
64
        # Test that local paths are properly normalized
 
65
        normalize_url = urlutils.normalize_url
 
66
 
 
67
        def norm_file(expected, path):
 
68
            url = normalize_url(path)
 
69
            self.assertStartsWith(url, 'file:///')
 
70
            if sys.platform == 'win32':
 
71
                url = url[len('file:///C:'):]
 
72
            else:
 
73
                url = url[len('file://'):]
 
74
 
 
75
            self.assertEndsWith(path, expected)
 
76
 
 
77
        norm_file('path/to/foo', 'path/to/foo')
 
78
        norm_file('/path/to/foo', '/path/to/foo')
 
79
        norm_file('path/to/foo', '../path/to/foo')
 
80
 
 
81
        # Local paths are assumed to *not* be escaped at all
 
82
        norm_file('uni/%C2%B5', u'uni/\xb5')
 
83
        norm_file('uni/%25C2%25B5', u'uni/%C2%B5')
 
84
        norm_file('uni/%20b', u'uni/ b')
 
85
        # All the crazy characters get escaped in local paths => file:/// urls
 
86
        norm_file('%27%3B/%3F%3A%40%26%3D%2B%24%2C%23%20', "';/?:@&=+$,#")
 
87
 
 
88
    def test_normalize_url_hybrid(self):
 
89
        # Anything with a scheme:// should be treated as a hybrid url
 
90
        # which changes what characters get escaped.
 
91
        normalize_url = urlutils.normalize_url
 
92
 
 
93
        eq = self.assertEqual
 
94
        eq('file:///foo/', normalize_url(u'file:///foo/'))
 
95
        eq('file:///foo/%20', normalize_url(u'file:///foo/ '))
 
96
        eq('file:///foo/%20', normalize_url(u'file:///foo/%20'))
 
97
        # Don't escape reserved characters
 
98
        eq('file:///ab_c.d-e/%f:?g&h=i+j;k,L#M$',
 
99
            normalize_url('file:///ab_c.d-e/%f:?g&h=i+j;k,L#M$'))
 
100
        eq('http://ab_c.d-e/%f:?g&h=i+j;k,L#M$',
 
101
            normalize_url('http://ab_c.d-e/%f:?g&h=i+j;k,L#M$'))
 
102
 
 
103
        # Escape unicode characters, but not already escaped chars
 
104
        eq('http://host/ab/%C2%B5/%C2%B5',
 
105
            normalize_url(u'http://host/ab/%C2%B5/\xb5'))
 
106
 
 
107
        # Normalize verifies URLs when they are not unicode
 
108
        # (indicating they did not come from the user)
 
109
        self.assertRaises(InvalidURL, normalize_url, 'http://host/\xb5')
 
110
        self.assertRaises(InvalidURL, normalize_url, 'http://host/ ')
 
111
 
 
112
    def test_url_scheme_re(self):
 
113
        # Test paths that may be URLs
 
114
        def test_one(url, scheme_and_path):
 
115
            """Assert that _url_scheme_re correctly matches
 
116
 
 
117
            :param scheme_and_path: The (scheme, path) that should be matched
 
118
                can be None, to indicate it should not match
 
119
            """
 
120
            m = urlutils._url_scheme_re.match(url)
 
121
            if scheme_and_path is None:
 
122
                self.assertEqual(None, m)
 
123
            else:
 
124
                self.assertEqual(scheme_and_path[0], m.group('scheme'))
 
125
                self.assertEqual(scheme_and_path[1], m.group('path'))
 
126
 
 
127
        # Local paths
 
128
        test_one('/path', None)
 
129
        test_one('C:/path', None)
 
130
        test_one('../path/to/foo', None)
 
131
        test_one(u'../path/to/fo\xe5', None)
 
132
 
 
133
        # Real URLS
 
134
        test_one('http://host/path/', ('http', 'host/path/'))
 
135
        test_one('sftp://host/path/to/foo', ('sftp', 'host/path/to/foo'))
 
136
        test_one('file:///usr/bin', ('file', '/usr/bin'))
 
137
        test_one('file:///C:/Windows', ('file', '/C:/Windows'))
 
138
        test_one('file:///C|/Windows', ('file', '/C|/Windows'))
 
139
        test_one(u'readonly+sftp://host/path/\xe5', ('readonly+sftp', u'host/path/\xe5'))
 
140
 
 
141
        # Weird stuff
 
142
        # Can't have slashes or colons in the scheme
 
143
        test_one('/path/to/://foo', None)
 
144
        test_one('path:path://foo', None)
 
145
        # Must have more than one character for scheme
 
146
        test_one('C://foo', None)
 
147
        test_one('ab://foo', ('ab', 'foo'))
 
148
 
 
149
    def test_dirname(self):
 
150
        # Test bzrlib.urlutils.dirname()
 
151
        dirname = urlutils.dirname
 
152
        if sys.platform == 'win32':
 
153
            self.assertRaises(InvalidURL, dirname, 'file:///path/to/foo')
 
154
            self.assertEqual('file:///C|/', dirname('file:///C|/foo'))
 
155
            self.assertEqual('file:///C|/', dirname('file:///C|/'))
 
156
        else:
 
157
            self.assertEqual('file:///', dirname('file:///foo'))
 
158
            self.assertEqual('file:///', dirname('file:///'))
 
159
 
 
160
        self.assertEqual('http://host/path/to', dirname('http://host/path/to/foo'))
 
161
        self.assertEqual('http://host/path/to', dirname('http://host/path/to/foo/'))
 
162
        self.assertEqual('http://host/path/to/foo',
 
163
            dirname('http://host/path/to/foo/', exclude_trailing_slash=False))
 
164
        self.assertEqual('http://host/', dirname('http://host/path'))
 
165
        self.assertEqual('http://host/', dirname('http://host/'))
 
166
        self.assertEqual('http://host', dirname('http://host'))
 
167
        self.assertEqual('http:///nohost', dirname('http:///nohost/path'))
 
168
 
 
169
        self.assertEqual('random+scheme://user:pass@ahost:port/',
 
170
            dirname('random+scheme://user:pass@ahost:port/path'))
 
171
        self.assertEqual('random+scheme://user:pass@ahost:port/',
 
172
            dirname('random+scheme://user:pass@ahost:port/path/'))
 
173
        self.assertEqual('random+scheme://user:pass@ahost:port/',
 
174
            dirname('random+scheme://user:pass@ahost:port/'))
 
175
 
 
176
        # relative paths
 
177
        self.assertEqual('path/to', dirname('path/to/foo'))
 
178
        self.assertEqual('path/to', dirname('path/to/foo/'))
 
179
        self.assertEqual('path/to/foo',
 
180
            dirname('path/to/foo/', exclude_trailing_slash=False))
 
181
        self.assertEqual('path/..', dirname('path/../foo'))
 
182
        self.assertEqual('../path', dirname('../path/foo'))
 
183
 
 
184
    def test_function_type(self):
 
185
        if sys.platform == 'win32':
 
186
            self.assertEqual(urlutils._win32_local_path_to_url, urlutils.local_path_to_url)
 
187
            self.assertEqual(urlutils._win32_local_path_from_url, urlutils.local_path_from_url)
 
188
        else:
 
189
            self.assertEqual(urlutils._posix_local_path_to_url, urlutils.local_path_to_url)
 
190
            self.assertEqual(urlutils._posix_local_path_from_url, urlutils.local_path_from_url)
 
191
 
 
192
    def test_posix_local_path_to_url(self):
 
193
        to_url = urlutils._posix_local_path_to_url
 
194
        self.assertEqual('file:///path/to/foo',
 
195
            to_url('/path/to/foo'))
 
196
        self.assertEqual('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s',
 
197
            to_url(u'/path/to/r\xe4ksm\xf6rg\xe5s'))
 
198
 
 
199
    def test_posix_local_path_from_url(self):
 
200
        from_url = urlutils._posix_local_path_from_url
 
201
        self.assertEqual('/path/to/foo',
 
202
            from_url('file:///path/to/foo'))
 
203
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
 
204
            from_url('file:///path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
 
205
        self.assertEqual(u'/path/to/r\xe4ksm\xf6rg\xe5s',
 
206
            from_url('file:///path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
 
207
 
 
208
        self.assertRaises(InvalidURL, from_url, '/path/to/foo')
 
209
 
 
210
    def test_win32_local_path_to_url(self):
 
211
        to_url = urlutils._win32_local_path_to_url
 
212
        self.assertEqual('file:///C|/path/to/foo',
 
213
            to_url('C:/path/to/foo'))
 
214
        self.assertEqual('file:///D|/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s',
 
215
            to_url(u'd:/path/to/r\xe4ksm\xf6rg\xe5s'))
 
216
 
 
217
    def test_win32_local_path_from_url(self):
 
218
        from_url = urlutils._win32_local_path_from_url
 
219
        self.assertEqual('C:/path/to/foo',
 
220
            from_url('file:///C|/path/to/foo'))
 
221
        self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
 
222
            from_url('file:///d|/path/to/r%C3%A4ksm%C3%B6rg%C3%A5s'))
 
223
        self.assertEqual(u'D:/path/to/r\xe4ksm\xf6rg\xe5s',
 
224
            from_url('file:///d|/path/to/r%c3%a4ksm%c3%b6rg%c3%a5s'))
 
225
 
 
226
        self.assertRaises(InvalidURL, from_url, '/path/to/foo')
 
227
        # Not a valid _win32 url, no drive letter
 
228
        self.assertRaises(InvalidURL, from_url, 'file:///path/to/foo')
 
229
 
 
230
    def test_split(self):
 
231
        # Test bzrlib.urlutils.split()
 
232
        split = urlutils.split
 
233
        if sys.platform == 'win32':
 
234
            self.assertRaises(InvalidURL, split, 'file:///path/to/foo')
 
235
            self.assertEqual(('file:///C|/', 'foo'), split('file:///C|/foo'))
 
236
            self.assertEqual(('file:///C|/', ''), split('file:///C|/'))
 
237
        else:
 
238
            self.assertEqual(('file:///', 'foo'), split('file:///foo'))
 
239
            self.assertEqual(('file:///', ''), split('file:///'))
 
240
 
 
241
        self.assertEqual(('http://host/path/to', 'foo'), split('http://host/path/to/foo'))
 
242
        self.assertEqual(('http://host/path/to', 'foo'), split('http://host/path/to/foo/'))
 
243
        self.assertEqual(('http://host/path/to/foo', ''),
 
244
            split('http://host/path/to/foo/', exclude_trailing_slash=False))
 
245
        self.assertEqual(('http://host/', 'path'), split('http://host/path'))
 
246
        self.assertEqual(('http://host/', ''), split('http://host/'))
 
247
        self.assertEqual(('http://host', ''), split('http://host'))
 
248
        self.assertEqual(('http:///nohost', 'path'), split('http:///nohost/path'))
 
249
 
 
250
        self.assertEqual(('random+scheme://user:pass@ahost:port/', 'path'),
 
251
            split('random+scheme://user:pass@ahost:port/path'))
 
252
        self.assertEqual(('random+scheme://user:pass@ahost:port/', 'path'),
 
253
            split('random+scheme://user:pass@ahost:port/path/'))
 
254
        self.assertEqual(('random+scheme://user:pass@ahost:port/', ''),
 
255
            split('random+scheme://user:pass@ahost:port/'))
 
256
 
 
257
        # relative paths
 
258
        self.assertEqual(('path/to', 'foo'), split('path/to/foo'))
 
259
        self.assertEqual(('path/to', 'foo'), split('path/to/foo/'))
 
260
        self.assertEqual(('path/to/foo', ''),
 
261
            split('path/to/foo/', exclude_trailing_slash=False))
 
262
        self.assertEqual(('path/..', 'foo'), split('path/../foo'))
 
263
        self.assertEqual(('../path', 'foo'), split('../path/foo'))
 
264
 
 
265
    def test_strip_trailing_slash(self):
 
266
        sts = urlutils.strip_trailing_slash
 
267
        if sys.platform == 'win32':
 
268
            self.assertEqual('file:///C|/', sts('file:///C|/'))
 
269
            self.assertEqual('file:///C|/foo', sts('file:///C|/foo'))
 
270
            self.assertEqual('file:///C|/foo', sts('file:///C|/foo/'))
 
271
        else:
 
272
            self.assertEqual('file:///', sts('file:///'))
 
273
            self.assertEqual('file:///foo', sts('file:///foo'))
 
274
            self.assertEqual('file:///foo', sts('file:///foo/'))
 
275
 
 
276
        self.assertEqual('http://host/', sts('http://host/'))
 
277
        self.assertEqual('http://host/foo', sts('http://host/foo'))
 
278
        self.assertEqual('http://host/foo', sts('http://host/foo/'))
 
279
 
 
280
        # No need to fail just because the slash is missing
 
281
        self.assertEqual('http://host', sts('http://host'))
 
282
        # TODO: jam 20060502 Should this raise InvalidURL?
 
283
        self.assertEqual('file://', sts('file://'))
 
284
 
 
285
        self.assertEqual('random+scheme://user:pass@ahost:port/path',
 
286
            sts('random+scheme://user:pass@ahost:port/path'))
 
287
        self.assertEqual('random+scheme://user:pass@ahost:port/path',
 
288
            sts('random+scheme://user:pass@ahost:port/path/'))
 
289
        self.assertEqual('random+scheme://user:pass@ahost:port/',
 
290
            sts('random+scheme://user:pass@ahost:port/'))
 
291
 
 
292
        # Make sure relative paths work too
 
293
        self.assertEqual('path/to/foo', sts('path/to/foo'))
 
294
        self.assertEqual('path/to/foo', sts('path/to/foo/'))
 
295
        self.assertEqual('../to/foo', sts('../to/foo/'))
 
296
        self.assertEqual('path/../foo', sts('path/../foo/'))
 
297
 
 
298
    def test_unescape_for_display(self):
 
299
        # Test that URLs are converted to nice unicode strings for display
 
300
        disp = urlutils.unescape_for_display
 
301
        eq = self.assertEqual
 
302
        eq('http://foo', disp('http://foo'))
 
303
        if sys.platform == 'win32':
 
304
            eq('C:/foo/path', disp('file:///C|foo/path'))
 
305
        else:
 
306
            eq('/foo/path', disp('file:///foo/path'))
 
307
 
 
308
        eq('http://foo/%2Fbaz', disp('http://foo/%2Fbaz'))
 
309
        eq(u'http://host/r\xe4ksm\xf6rg\xe5s', disp('http://host/r%C3%A4ksm%C3%B6rg%C3%A5s'))
 
310
 
 
311
        # Make sure special escaped characters stay escaped
 
312
        eq(u'http://host/%3B%2F%3F%3A%40%26%3D%2B%24%2C%23',
 
313
            disp('http://host/%3B%2F%3F%3A%40%26%3D%2B%24%2C%23'))
 
314
 
 
315
        # Can we handle sections that don't have utf-8 encoding?
 
316
        eq(u'http://host/%EE%EE%EE/r\xe4ksm\xf6rg\xe5s',
 
317
            disp('http://host/%EE%EE%EE/r%C3%A4ksm%C3%B6rg%C3%A5s'))
 
318
 
 
319
    def test_escape(self):
 
320
        self.assertEqual('%25', urlutils.escape('%'))
 
321
        self.assertEqual('%C3%A5', urlutils.escape(u'\xe5'))
 
322
 
 
323
    def test_unescape(self):
 
324
        self.assertEqual('%', urlutils.unescape('%25'))
 
325
        self.assertEqual(u'\xe5', urlutils.unescape('%C3%A5'))
 
326
 
 
327
        self.assertRaises(InvalidURL, urlutils.unescape, u'\xe5')
 
328
        self.assertRaises(InvalidURL, urlutils.unescape, '\xe5')
 
329
        self.assertRaises(InvalidURL, urlutils.unescape, '%E5')
 
330
 
 
331
    def test_escape_unescape(self):
 
332
        self.assertEqual(u'\xe5', urlutils.unescape(urlutils.escape(u'\xe5')))
 
333
        self.assertEqual('%', urlutils.unescape(urlutils.escape('%')))
 
334