blob: 4579c479d1478bbf06425104ee2f74531499514b [file] [log] [blame]
Brett Cannon74bfd702003-04-25 09:39:47 +00001"""Regresssion tests for urllib"""
2
Jeremy Hylton6102e292000-08-31 15:48:10 +00003import urllib
Hye-Shik Chang39aef792004-06-05 13:30:56 +00004import httplib
Brett Cannon74bfd702003-04-25 09:39:47 +00005import unittest
6from test import test_support
7import os
8import mimetools
Georg Brandl5a650a22005-08-26 08:51:34 +00009import tempfile
Hye-Shik Chang39aef792004-06-05 13:30:56 +000010import StringIO
Jeremy Hylton6102e292000-08-31 15:48:10 +000011
Brett Cannon74bfd702003-04-25 09:39:47 +000012def hexescape(char):
13 """Escape char as RFC 2396 specifies"""
14 hex_repr = hex(ord(char))[2:].upper()
15 if len(hex_repr) == 1:
16 hex_repr = "0%s" % hex_repr
17 return "%" + hex_repr
Jeremy Hylton6102e292000-08-31 15:48:10 +000018
Brett Cannon74bfd702003-04-25 09:39:47 +000019class urlopen_FileTests(unittest.TestCase):
20 """Test urlopen() opening a temporary file.
Jeremy Hylton6102e292000-08-31 15:48:10 +000021
Brett Cannon74bfd702003-04-25 09:39:47 +000022 Try to test as much functionality as possible so as to cut down on reliance
Andrew M. Kuchlingf1a2f9e2004-06-29 13:07:53 +000023 on connecting to the Net for testing.
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000024
Brett Cannon74bfd702003-04-25 09:39:47 +000025 """
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000026
Brett Cannon74bfd702003-04-25 09:39:47 +000027 def setUp(self):
28 """Setup of a temp file to use for testing"""
29 self.text = "test_urllib: %s\n" % self.__class__.__name__
Guido van Rossum51735b02003-04-25 15:01:05 +000030 FILE = file(test_support.TESTFN, 'wb')
Brett Cannon74bfd702003-04-25 09:39:47 +000031 try:
32 FILE.write(self.text)
33 finally:
34 FILE.close()
35 self.pathname = test_support.TESTFN
36 self.returned_obj = urllib.urlopen("file:%s" % self.pathname)
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000037
Brett Cannon74bfd702003-04-25 09:39:47 +000038 def tearDown(self):
39 """Shut down the open object"""
40 self.returned_obj.close()
Brett Cannon19691362003-04-29 05:08:06 +000041 os.remove(test_support.TESTFN)
Jeremy Hylton7ae51bf2000-09-14 16:59:07 +000042
Brett Cannon74bfd702003-04-25 09:39:47 +000043 def test_interface(self):
44 # Make sure object returned by urlopen() has the specified methods
45 for attr in ("read", "readline", "readlines", "fileno",
46 "close", "info", "geturl", "__iter__"):
47 self.assert_(hasattr(self.returned_obj, attr),
48 "object returned by urlopen() lacks %s attribute" %
49 attr)
Skip Montanaroe78b92a2001-01-20 20:22:30 +000050
Brett Cannon74bfd702003-04-25 09:39:47 +000051 def test_read(self):
52 self.assertEqual(self.text, self.returned_obj.read())
Skip Montanaro080c9972001-01-28 21:12:22 +000053
Brett Cannon74bfd702003-04-25 09:39:47 +000054 def test_readline(self):
55 self.assertEqual(self.text, self.returned_obj.readline())
56 self.assertEqual('', self.returned_obj.readline(),
57 "calling readline() after exhausting the file did not"
58 " return an empty string")
Skip Montanaro080c9972001-01-28 21:12:22 +000059
Brett Cannon74bfd702003-04-25 09:39:47 +000060 def test_readlines(self):
61 lines_list = self.returned_obj.readlines()
62 self.assertEqual(len(lines_list), 1,
63 "readlines() returned the wrong number of lines")
64 self.assertEqual(lines_list[0], self.text,
65 "readlines() returned improper text")
Skip Montanaro080c9972001-01-28 21:12:22 +000066
Brett Cannon74bfd702003-04-25 09:39:47 +000067 def test_fileno(self):
68 file_num = self.returned_obj.fileno()
69 self.assert_(isinstance(file_num, int),
70 "fileno() did not return an int")
71 self.assertEqual(os.read(file_num, len(self.text)), self.text,
72 "Reading on the file descriptor returned by fileno() "
73 "did not return the expected text")
Skip Montanaroe78b92a2001-01-20 20:22:30 +000074
Brett Cannon74bfd702003-04-25 09:39:47 +000075 def test_close(self):
76 # Test close() by calling it hear and then having it be called again
77 # by the tearDown() method for the test
78 self.returned_obj.close()
Skip Montanaro080c9972001-01-28 21:12:22 +000079
Brett Cannon74bfd702003-04-25 09:39:47 +000080 def test_info(self):
81 self.assert_(isinstance(self.returned_obj.info(), mimetools.Message))
Skip Montanaroe78b92a2001-01-20 20:22:30 +000082
Brett Cannon74bfd702003-04-25 09:39:47 +000083 def test_geturl(self):
84 self.assertEqual(self.returned_obj.geturl(), self.pathname)
Skip Montanaro080c9972001-01-28 21:12:22 +000085
Brett Cannon74bfd702003-04-25 09:39:47 +000086 def test_iter(self):
87 # Test iterator
88 # Don't need to count number of iterations since test would fail the
89 # instant it returned anything beyond the first line from the
90 # comparison
91 for line in self.returned_obj.__iter__():
92 self.assertEqual(line, self.text)
Skip Montanaro080c9972001-01-28 21:12:22 +000093
Hye-Shik Chang39aef792004-06-05 13:30:56 +000094class urlopen_HttpTests(unittest.TestCase):
95 """Test urlopen() opening a fake http connection."""
96
97 def fakehttp(self, fakedata):
98 class FakeSocket(StringIO.StringIO):
99 def sendall(self, str): pass
100 def makefile(self, mode, name): return self
101 def read(self, amt=None):
102 if self.closed: return ''
103 return StringIO.StringIO.read(self, amt)
104 def readline(self, length=None):
105 if self.closed: return ''
106 return StringIO.StringIO.readline(self, length)
107 class FakeHTTPConnection(httplib.HTTPConnection):
108 def connect(self):
109 self.sock = FakeSocket(fakedata)
110 assert httplib.HTTP._connection_class == httplib.HTTPConnection
111 httplib.HTTP._connection_class = FakeHTTPConnection
112
113 def unfakehttp(self):
114 httplib.HTTP._connection_class = httplib.HTTPConnection
115
116 def test_read(self):
117 self.fakehttp('Hello!')
118 try:
119 fp = urllib.urlopen("http://python.org/")
120 self.assertEqual(fp.readline(), 'Hello!')
121 self.assertEqual(fp.readline(), '')
122 finally:
123 self.unfakehttp()
124
Brett Cannon19691362003-04-29 05:08:06 +0000125class urlretrieve_FileTests(unittest.TestCase):
Brett Cannon74bfd702003-04-25 09:39:47 +0000126 """Test urllib.urlretrieve() on local files"""
Skip Montanaro080c9972001-01-28 21:12:22 +0000127
Brett Cannon19691362003-04-29 05:08:06 +0000128 def setUp(self):
Georg Brandl5a650a22005-08-26 08:51:34 +0000129 # Create a list of temporary files. Each item in the list is a file
130 # name (absolute path or relative to the current working directory).
131 # All files in this list will be deleted in the tearDown method. Note,
132 # this only helps to makes sure temporary files get deleted, but it
133 # does nothing about trying to close files that may still be open. It
134 # is the responsibility of the developer to properly close files even
135 # when exceptional conditions occur.
136 self.tempFiles = []
137
Brett Cannon19691362003-04-29 05:08:06 +0000138 # Create a temporary file.
Georg Brandl5a650a22005-08-26 08:51:34 +0000139 self.registerFileForCleanUp(test_support.TESTFN)
Brett Cannon19691362003-04-29 05:08:06 +0000140 self.text = 'testing urllib.urlretrieve'
Georg Brandl5a650a22005-08-26 08:51:34 +0000141 try:
142 FILE = file(test_support.TESTFN, 'wb')
143 FILE.write(self.text)
144 FILE.close()
145 finally:
146 try: FILE.close()
147 except: pass
Brett Cannon19691362003-04-29 05:08:06 +0000148
149 def tearDown(self):
Georg Brandl5a650a22005-08-26 08:51:34 +0000150 # Delete the temporary files.
151 for each in self.tempFiles:
152 try: os.remove(each)
153 except: pass
154
155 def constructLocalFileUrl(self, filePath):
156 return "file://%s" % urllib.pathname2url(os.path.abspath(filePath))
157
158 def createNewTempFile(self, data=""):
159 """Creates a new temporary file containing the specified data,
160 registers the file for deletion during the test fixture tear down, and
161 returns the absolute path of the file."""
162
163 newFd, newFilePath = tempfile.mkstemp()
164 try:
165 self.registerFileForCleanUp(newFilePath)
166 newFile = os.fdopen(newFd, "wb")
167 newFile.write(data)
168 newFile.close()
169 finally:
170 try: newFile.close()
171 except: pass
172 return newFilePath
173
174 def registerFileForCleanUp(self, fileName):
175 self.tempFiles.append(fileName)
Brett Cannon19691362003-04-29 05:08:06 +0000176
177 def test_basic(self):
178 # Make sure that a local file just gets its own location returned and
179 # a headers value is returned.
180 result = urllib.urlretrieve("file:%s" % test_support.TESTFN)
181 self.assertEqual(result[0], test_support.TESTFN)
182 self.assert_(isinstance(result[1], mimetools.Message),
183 "did not get a mimetools.Message instance as second "
184 "returned value")
185
186 def test_copy(self):
187 # Test that setting the filename argument works.
188 second_temp = "%s.2" % test_support.TESTFN
Georg Brandl5a650a22005-08-26 08:51:34 +0000189 self.registerFileForCleanUp(second_temp)
190 result = urllib.urlretrieve(self.constructLocalFileUrl(
191 test_support.TESTFN), second_temp)
Brett Cannon19691362003-04-29 05:08:06 +0000192 self.assertEqual(second_temp, result[0])
193 self.assert_(os.path.exists(second_temp), "copy of the file was not "
194 "made")
195 FILE = file(second_temp, 'rb')
196 try:
197 text = FILE.read()
Brett Cannon19691362003-04-29 05:08:06 +0000198 FILE.close()
Georg Brandl5a650a22005-08-26 08:51:34 +0000199 finally:
200 try: FILE.close()
201 except: pass
Brett Cannon19691362003-04-29 05:08:06 +0000202 self.assertEqual(self.text, text)
203
204 def test_reporthook(self):
205 # Make sure that the reporthook works.
206 def hooktester(count, block_size, total_size, count_holder=[0]):
207 self.assert_(isinstance(count, int))
208 self.assert_(isinstance(block_size, int))
209 self.assert_(isinstance(total_size, int))
210 self.assertEqual(count, count_holder[0])
211 count_holder[0] = count_holder[0] + 1
212 second_temp = "%s.2" % test_support.TESTFN
Georg Brandl5a650a22005-08-26 08:51:34 +0000213 self.registerFileForCleanUp(second_temp)
214 urllib.urlretrieve(self.constructLocalFileUrl(test_support.TESTFN),
215 second_temp, hooktester)
216
217 def test_reporthook_0_bytes(self):
218 # Test on zero length file. Should call reporthook only 1 time.
219 report = []
220 def hooktester(count, block_size, total_size, _report=report):
221 _report.append((count, block_size, total_size))
222 srcFileName = self.createNewTempFile()
223 urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
224 test_support.TESTFN, hooktester)
225 self.assertEqual(len(report), 1)
226 self.assertEqual(report[0][2], 0)
227
228 def test_reporthook_5_bytes(self):
229 # Test on 5 byte file. Should call reporthook only 2 times (once when
230 # the "network connection" is established and once when the block is
231 # read). Since the block size is 8192 bytes, only one block read is
232 # required to read the entire file.
233 report = []
234 def hooktester(count, block_size, total_size, _report=report):
235 _report.append((count, block_size, total_size))
236 srcFileName = self.createNewTempFile("x" * 5)
237 urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
238 test_support.TESTFN, hooktester)
239 self.assertEqual(len(report), 2)
240 self.assertEqual(report[0][1], 8192)
241 self.assertEqual(report[0][2], 5)
242
243 def test_reporthook_8193_bytes(self):
244 # Test on 8193 byte file. Should call reporthook only 3 times (once
245 # when the "network connection" is established, once for the next 8192
246 # bytes, and once for the last byte).
247 report = []
248 def hooktester(count, block_size, total_size, _report=report):
249 _report.append((count, block_size, total_size))
250 srcFileName = self.createNewTempFile("x" * 8193)
251 urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
252 test_support.TESTFN, hooktester)
253 self.assertEqual(len(report), 3)
254 self.assertEqual(report[0][1], 8192)
255 self.assertEqual(report[0][2], 8193)
Skip Montanaro080c9972001-01-28 21:12:22 +0000256
Brett Cannon74bfd702003-04-25 09:39:47 +0000257class QuotingTests(unittest.TestCase):
258 """Tests for urllib.quote() and urllib.quote_plus()
Tim Petersc2659cf2003-05-12 20:19:37 +0000259
Brett Cannon74bfd702003-04-25 09:39:47 +0000260 According to RFC 2396 ("Uniform Resource Identifiers), to escape a
261 character you write it as '%' + <2 character US-ASCII hex value>. The Python
262 code of ``'%' + hex(ord(<character>))[2:]`` escapes a character properly.
263 Case does not matter on the hex letters.
264
265 The various character sets specified are:
Tim Petersc2659cf2003-05-12 20:19:37 +0000266
Brett Cannon74bfd702003-04-25 09:39:47 +0000267 Reserved characters : ";/?:@&=+$,"
268 Have special meaning in URIs and must be escaped if not being used for
269 their special meaning
270 Data characters : letters, digits, and "-_.!~*'()"
271 Unreserved and do not need to be escaped; can be, though, if desired
272 Control characters : 0x00 - 0x1F, 0x7F
273 Have no use in URIs so must be escaped
274 space : 0x20
275 Must be escaped
276 Delimiters : '<>#%"'
277 Must be escaped
278 Unwise : "{}|\^[]`"
279 Must be escaped
Tim Petersc2659cf2003-05-12 20:19:37 +0000280
Brett Cannon74bfd702003-04-25 09:39:47 +0000281 """
282
283 def test_never_quote(self):
284 # Make sure quote() does not quote letters, digits, and "_,.-"
285 do_not_quote = '' .join(["ABCDEFGHIJKLMNOPQRSTUVWXYZ",
286 "abcdefghijklmnopqrstuvwxyz",
287 "0123456789",
288 "_.-"])
289 result = urllib.quote(do_not_quote)
290 self.assertEqual(do_not_quote, result,
291 "using quote(): %s != %s" % (do_not_quote, result))
292 result = urllib.quote_plus(do_not_quote)
293 self.assertEqual(do_not_quote, result,
294 "using quote_plus(): %s != %s" % (do_not_quote, result))
295
296 def test_default_safe(self):
297 # Test '/' is default value for 'safe' parameter
298 self.assertEqual(urllib.quote.func_defaults[0], '/')
299
300 def test_safe(self):
301 # Test setting 'safe' parameter does what it should do
302 quote_by_default = "<>"
303 result = urllib.quote(quote_by_default, safe=quote_by_default)
304 self.assertEqual(quote_by_default, result,
305 "using quote(): %s != %s" % (quote_by_default, result))
306 result = urllib.quote_plus(quote_by_default, safe=quote_by_default)
307 self.assertEqual(quote_by_default, result,
308 "using quote_plus(): %s != %s" %
309 (quote_by_default, result))
310
311 def test_default_quoting(self):
312 # Make sure all characters that should be quoted are by default sans
313 # space (separate test for that).
314 should_quote = [chr(num) for num in range(32)] # For 0x00 - 0x1F
315 should_quote.append('<>#%"{}|\^[]`')
316 should_quote.append(chr(127)) # For 0x7F
317 should_quote = ''.join(should_quote)
318 for char in should_quote:
319 result = urllib.quote(char)
320 self.assertEqual(hexescape(char), result,
321 "using quote(): %s should be escaped to %s, not %s" %
322 (char, hexescape(char), result))
323 result = urllib.quote_plus(char)
324 self.assertEqual(hexescape(char), result,
325 "using quote_plus(): "
Tim Petersc2659cf2003-05-12 20:19:37 +0000326 "%s should be escapes to %s, not %s" %
Brett Cannon74bfd702003-04-25 09:39:47 +0000327 (char, hexescape(char), result))
328 del should_quote
329 partial_quote = "ab[]cd"
330 expected = "ab%5B%5Dcd"
331 result = urllib.quote(partial_quote)
332 self.assertEqual(expected, result,
333 "using quote(): %s != %s" % (expected, result))
334 self.assertEqual(expected, result,
335 "using quote_plus(): %s != %s" % (expected, result))
336
337 def test_quoting_space(self):
338 # Make sure quote() and quote_plus() handle spaces as specified in
339 # their unique way
340 result = urllib.quote(' ')
341 self.assertEqual(result, hexescape(' '),
342 "using quote(): %s != %s" % (result, hexescape(' ')))
343 result = urllib.quote_plus(' ')
344 self.assertEqual(result, '+',
345 "using quote_plus(): %s != +" % result)
346 given = "a b cd e f"
347 expect = given.replace(' ', hexescape(' '))
348 result = urllib.quote(given)
349 self.assertEqual(expect, result,
350 "using quote(): %s != %s" % (expect, result))
351 expect = given.replace(' ', '+')
352 result = urllib.quote_plus(given)
353 self.assertEqual(expect, result,
354 "using quote_plus(): %s != %s" % (expect, result))
355
Raymond Hettinger2bdec7b2005-09-10 14:30:09 +0000356 def test_quoting_plus(self):
357 self.assertEqual(urllib.quote_plus('alpha+beta gamma'),
358 'alpha%2Bbeta+gamma')
359 self.assertEqual(urllib.quote_plus('alpha+beta gamma', '+'),
360 'alpha+beta+gamma')
361
Brett Cannon74bfd702003-04-25 09:39:47 +0000362class UnquotingTests(unittest.TestCase):
363 """Tests for unquote() and unquote_plus()
Tim Petersc2659cf2003-05-12 20:19:37 +0000364
Brett Cannon74bfd702003-04-25 09:39:47 +0000365 See the doc string for quoting_Tests for details on quoting and such.
366
367 """
368
369 def test_unquoting(self):
370 # Make sure unquoting of all ASCII values works
371 escape_list = []
372 for num in range(128):
373 given = hexescape(chr(num))
374 expect = chr(num)
375 result = urllib.unquote(given)
376 self.assertEqual(expect, result,
377 "using unquote(): %s != %s" % (expect, result))
378 result = urllib.unquote_plus(given)
379 self.assertEqual(expect, result,
380 "using unquote_plus(): %s != %s" %
381 (expect, result))
382 escape_list.append(given)
383 escape_string = ''.join(escape_list)
384 del escape_list
385 result = urllib.unquote(escape_string)
386 self.assertEqual(result.count('%'), 1,
387 "using quote(): not all characters escaped; %s" %
388 result)
389 result = urllib.unquote(escape_string)
390 self.assertEqual(result.count('%'), 1,
391 "using unquote(): not all characters escaped: "
392 "%s" % result)
393
394 def test_unquoting_parts(self):
395 # Make sure unquoting works when have non-quoted characters
396 # interspersed
397 given = 'ab%sd' % hexescape('c')
398 expect = "abcd"
399 result = urllib.unquote(given)
400 self.assertEqual(expect, result,
401 "using quote(): %s != %s" % (expect, result))
402 result = urllib.unquote_plus(given)
403 self.assertEqual(expect, result,
404 "using unquote_plus(): %s != %s" % (expect, result))
Tim Petersc2659cf2003-05-12 20:19:37 +0000405
Brett Cannon74bfd702003-04-25 09:39:47 +0000406 def test_unquoting_plus(self):
407 # Test difference between unquote() and unquote_plus()
408 given = "are+there+spaces..."
409 expect = given
410 result = urllib.unquote(given)
411 self.assertEqual(expect, result,
412 "using unquote(): %s != %s" % (expect, result))
413 expect = given.replace('+', ' ')
414 result = urllib.unquote_plus(given)
415 self.assertEqual(expect, result,
416 "using unquote_plus(): %s != %s" % (expect, result))
417
Raymond Hettinger4b0f20d2005-10-15 16:41:53 +0000418 def test_unquote_with_unicode(self):
419 r = urllib.unquote(u'br%C3%BCckner_sapporo_20050930.doc')
420 self.assertEqual(r, u'br\xc3\xbcckner_sapporo_20050930.doc')
421
Brett Cannon74bfd702003-04-25 09:39:47 +0000422class urlencode_Tests(unittest.TestCase):
423 """Tests for urlencode()"""
424
425 def help_inputtype(self, given, test_type):
426 """Helper method for testing different input types.
Tim Petersc2659cf2003-05-12 20:19:37 +0000427
Brett Cannon74bfd702003-04-25 09:39:47 +0000428 'given' must lead to only the pairs:
429 * 1st, 1
430 * 2nd, 2
431 * 3rd, 3
Tim Petersc2659cf2003-05-12 20:19:37 +0000432
Brett Cannon74bfd702003-04-25 09:39:47 +0000433 Test cannot assume anything about order. Docs make no guarantee and
434 have possible dictionary input.
Tim Petersc2659cf2003-05-12 20:19:37 +0000435
Brett Cannon74bfd702003-04-25 09:39:47 +0000436 """
437 expect_somewhere = ["1st=1", "2nd=2", "3rd=3"]
438 result = urllib.urlencode(given)
439 for expected in expect_somewhere:
440 self.assert_(expected in result,
441 "testing %s: %s not found in %s" %
442 (test_type, expected, result))
443 self.assertEqual(result.count('&'), 2,
444 "testing %s: expected 2 '&'s; got %s" %
445 (test_type, result.count('&')))
446 amp_location = result.index('&')
447 on_amp_left = result[amp_location - 1]
448 on_amp_right = result[amp_location + 1]
449 self.assert_(on_amp_left.isdigit() and on_amp_right.isdigit(),
450 "testing %s: '&' not located in proper place in %s" %
451 (test_type, result))
452 self.assertEqual(len(result), (5 * 3) + 2, #5 chars per thing and amps
453 "testing %s: "
454 "unexpected number of characters: %s != %s" %
455 (test_type, len(result), (5 * 3) + 2))
456
457 def test_using_mapping(self):
458 # Test passing in a mapping object as an argument.
459 self.help_inputtype({"1st":'1', "2nd":'2', "3rd":'3'},
460 "using dict as input type")
461
462 def test_using_sequence(self):
463 # Test passing in a sequence of two-item sequences as an argument.
464 self.help_inputtype([('1st', '1'), ('2nd', '2'), ('3rd', '3')],
465 "using sequence of two-item tuples as input")
466
467 def test_quoting(self):
468 # Make sure keys and values are quoted using quote_plus()
469 given = {"&":"="}
470 expect = "%s=%s" % (hexescape('&'), hexescape('='))
471 result = urllib.urlencode(given)
472 self.assertEqual(expect, result)
473 given = {"key name":"A bunch of pluses"}
474 expect = "key+name=A+bunch+of+pluses"
475 result = urllib.urlencode(given)
476 self.assertEqual(expect, result)
477
478 def test_doseq(self):
479 # Test that passing True for 'doseq' parameter works correctly
480 given = {'sequence':['1', '2', '3']}
481 expect = "sequence=%s" % urllib.quote_plus(str(['1', '2', '3']))
482 result = urllib.urlencode(given)
483 self.assertEqual(expect, result)
484 result = urllib.urlencode(given, True)
485 for value in given["sequence"]:
486 expect = "sequence=%s" % value
487 self.assert_(expect in result,
488 "%s not found in %s" % (expect, result))
489 self.assertEqual(result.count('&'), 2,
490 "Expected 2 '&'s, got %s" % result.count('&'))
491
492class Pathname_Tests(unittest.TestCase):
493 """Test pathname2url() and url2pathname()"""
494
495 def test_basic(self):
496 # Make sure simple tests pass
497 expected_path = os.path.join("parts", "of", "a", "path")
498 expected_url = "parts/of/a/path"
499 result = urllib.pathname2url(expected_path)
500 self.assertEqual(expected_url, result,
501 "pathname2url() failed; %s != %s" %
502 (result, expected_url))
503 result = urllib.url2pathname(expected_url)
504 self.assertEqual(expected_path, result,
505 "url2pathame() failed; %s != %s" %
506 (result, expected_path))
507
508 def test_quoting(self):
509 # Test automatic quoting and unquoting works for pathnam2url() and
510 # url2pathname() respectively
511 given = os.path.join("needs", "quot=ing", "here")
512 expect = "needs/%s/here" % urllib.quote("quot=ing")
513 result = urllib.pathname2url(given)
514 self.assertEqual(expect, result,
515 "pathname2url() failed; %s != %s" %
516 (expect, result))
517 expect = given
518 result = urllib.url2pathname(result)
519 self.assertEqual(expect, result,
520 "url2pathname() failed; %s != %s" %
521 (expect, result))
522 given = os.path.join("make sure", "using_quote")
523 expect = "%s/using_quote" % urllib.quote("make sure")
524 result = urllib.pathname2url(given)
525 self.assertEqual(expect, result,
526 "pathname2url() failed; %s != %s" %
527 (expect, result))
528 given = "make+sure/using_unquote"
529 expect = os.path.join("make+sure", "using_unquote")
530 result = urllib.url2pathname(given)
531 self.assertEqual(expect, result,
532 "url2pathname() failed; %s != %s" %
533 (expect, result))
Tim Petersc2659cf2003-05-12 20:19:37 +0000534
Skip Montanaro080c9972001-01-28 21:12:22 +0000535
536
Brett Cannon74bfd702003-04-25 09:39:47 +0000537def test_main():
Walter Dörwald21d3a322003-05-01 17:45:56 +0000538 test_support.run_unittest(
539 urlopen_FileTests,
Hye-Shik Chang39aef792004-06-05 13:30:56 +0000540 urlopen_HttpTests,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000541 urlretrieve_FileTests,
542 QuotingTests,
543 UnquotingTests,
544 urlencode_Tests,
545 Pathname_Tests
546 )
Brett Cannon74bfd702003-04-25 09:39:47 +0000547
548
549
550if __name__ == '__main__':
551 test_main()