PyXR

c:\python24\lib \ test \ test_urllib.py



0001 """Regresssion tests for urllib"""
0002 
0003 import urllib
0004 import httplib
0005 import unittest
0006 from test import test_support
0007 import os
0008 import mimetools
0009 import StringIO
0010 
0011 def hexescape(char):
0012     """Escape char as RFC 2396 specifies"""
0013     hex_repr = hex(ord(char))[2:].upper()
0014     if len(hex_repr) == 1:
0015         hex_repr = "0%s" % hex_repr
0016     return "%" + hex_repr
0017 
0018 class urlopen_FileTests(unittest.TestCase):
0019     """Test urlopen() opening a temporary file.
0020 
0021     Try to test as much functionality as possible so as to cut down on reliance
0022     on connecting to the Net for testing.
0023 
0024     """
0025 
0026     def setUp(self):
0027         """Setup of a temp file to use for testing"""
0028         self.text = "test_urllib: %s\n" % self.__class__.__name__
0029         FILE = file(test_support.TESTFN, 'wb')
0030         try:
0031             FILE.write(self.text)
0032         finally:
0033             FILE.close()
0034         self.pathname = test_support.TESTFN
0035         self.returned_obj = urllib.urlopen("file:%s" % self.pathname)
0036 
0037     def tearDown(self):
0038         """Shut down the open object"""
0039         self.returned_obj.close()
0040         os.remove(test_support.TESTFN)
0041 
0042     def test_interface(self):
0043         # Make sure object returned by urlopen() has the specified methods
0044         for attr in ("read", "readline", "readlines", "fileno",
0045                      "close", "info", "geturl", "__iter__"):
0046             self.assert_(hasattr(self.returned_obj, attr),
0047                          "object returned by urlopen() lacks %s attribute" %
0048                          attr)
0049 
0050     def test_read(self):
0051         self.assertEqual(self.text, self.returned_obj.read())
0052 
0053     def test_readline(self):
0054         self.assertEqual(self.text, self.returned_obj.readline())
0055         self.assertEqual('', self.returned_obj.readline(),
0056                          "calling readline() after exhausting the file did not"
0057                          " return an empty string")
0058 
0059     def test_readlines(self):
0060         lines_list = self.returned_obj.readlines()
0061         self.assertEqual(len(lines_list), 1,
0062                          "readlines() returned the wrong number of lines")
0063         self.assertEqual(lines_list[0], self.text,
0064                          "readlines() returned improper text")
0065 
0066     def test_fileno(self):
0067         file_num = self.returned_obj.fileno()
0068         self.assert_(isinstance(file_num, int),
0069                      "fileno() did not return an int")
0070         self.assertEqual(os.read(file_num, len(self.text)), self.text,
0071                          "Reading on the file descriptor returned by fileno() "
0072                          "did not return the expected text")
0073 
0074     def test_close(self):
0075         # Test close() by calling it hear and then having it be called again
0076         # by the tearDown() method for the test
0077         self.returned_obj.close()
0078 
0079     def test_info(self):
0080         self.assert_(isinstance(self.returned_obj.info(), mimetools.Message))
0081 
0082     def test_geturl(self):
0083         self.assertEqual(self.returned_obj.geturl(), self.pathname)
0084 
0085     def test_iter(self):
0086         # Test iterator
0087         # Don't need to count number of iterations since test would fail the
0088         # instant it returned anything beyond the first line from the
0089         # comparison
0090         for line in self.returned_obj.__iter__():
0091             self.assertEqual(line, self.text)
0092 
0093 class urlopen_HttpTests(unittest.TestCase):
0094     """Test urlopen() opening a fake http connection."""
0095 
0096     def fakehttp(self, fakedata):
0097         class FakeSocket(StringIO.StringIO):
0098             def sendall(self, str): pass
0099             def makefile(self, mode, name): return self
0100             def read(self, amt=None):
0101                 if self.closed: return ''
0102                 return StringIO.StringIO.read(self, amt)
0103             def readline(self, length=None):
0104                 if self.closed: return ''
0105                 return StringIO.StringIO.readline(self, length)
0106         class FakeHTTPConnection(httplib.HTTPConnection):
0107             def connect(self):
0108                 self.sock = FakeSocket(fakedata)
0109         assert httplib.HTTP._connection_class == httplib.HTTPConnection
0110         httplib.HTTP._connection_class = FakeHTTPConnection
0111 
0112     def unfakehttp(self):
0113         httplib.HTTP._connection_class = httplib.HTTPConnection
0114 
0115     def test_read(self):
0116         self.fakehttp('Hello!')
0117         try:
0118             fp = urllib.urlopen("http://python.org/")
0119             self.assertEqual(fp.readline(), 'Hello!')
0120             self.assertEqual(fp.readline(), '')
0121         finally:
0122             self.unfakehttp()
0123 
0124 class urlretrieve_FileTests(unittest.TestCase):
0125     """Test urllib.urlretrieve() on local files"""
0126 
0127     def setUp(self):
0128         # Create a temporary file.
0129         self.text = 'testing urllib.urlretrieve'
0130         FILE = file(test_support.TESTFN, 'wb')
0131         FILE.write(self.text)
0132         FILE.close()
0133 
0134     def tearDown(self):
0135         # Delete the temporary file.
0136         os.remove(test_support.TESTFN)
0137 
0138     def test_basic(self):
0139         # Make sure that a local file just gets its own location returned and
0140         # a headers value is returned.
0141         result = urllib.urlretrieve("file:%s" % test_support.TESTFN)
0142         self.assertEqual(result[0], test_support.TESTFN)
0143         self.assert_(isinstance(result[1], mimetools.Message),
0144                      "did not get a mimetools.Message instance as second "
0145                      "returned value")
0146 
0147     def test_copy(self):
0148         # Test that setting the filename argument works.
0149         second_temp = "%s.2" % test_support.TESTFN
0150         result = urllib.urlretrieve("file:%s" % test_support.TESTFN, second_temp)
0151         self.assertEqual(second_temp, result[0])
0152         self.assert_(os.path.exists(second_temp), "copy of the file was not "
0153                                                   "made")
0154         FILE = file(second_temp, 'rb')
0155         try:
0156             text = FILE.read()
0157         finally:
0158             FILE.close()
0159         self.assertEqual(self.text, text)
0160 
0161     def test_reporthook(self):
0162         # Make sure that the reporthook works.
0163         def hooktester(count, block_size, total_size, count_holder=[0]):
0164             self.assert_(isinstance(count, int))
0165             self.assert_(isinstance(block_size, int))
0166             self.assert_(isinstance(total_size, int))
0167             self.assertEqual(count, count_holder[0])
0168             count_holder[0] = count_holder[0] + 1
0169         second_temp = "%s.2" % test_support.TESTFN
0170         urllib.urlretrieve(test_support.TESTFN, second_temp, hooktester)
0171         os.remove(second_temp)
0172 
0173 class QuotingTests(unittest.TestCase):
0174     """Tests for urllib.quote() and urllib.quote_plus()
0175 
0176     According to RFC 2396 ("Uniform Resource Identifiers), to escape a
0177     character you write it as '%' + <2 character US-ASCII hex value>.  The Python
0178     code of ``'%' + hex(ord(<character>))[2:]`` escapes a character properly.
0179     Case does not matter on the hex letters.
0180 
0181     The various character sets specified are:
0182 
0183     Reserved characters : ";/?:@&=+$,"
0184         Have special meaning in URIs and must be escaped if not being used for
0185         their special meaning
0186     Data characters : letters, digits, and "-_.!~*'()"
0187         Unreserved and do not need to be escaped; can be, though, if desired
0188     Control characters : 0x00 - 0x1F, 0x7F
0189         Have no use in URIs so must be escaped
0190     space : 0x20
0191         Must be escaped
0192     Delimiters : '<>#%"'
0193         Must be escaped
0194     Unwise : "{}|\^[]`"
0195         Must be escaped
0196 
0197     """
0198 
0199     def test_never_quote(self):
0200         # Make sure quote() does not quote letters, digits, and "_,.-"
0201         do_not_quote = '' .join(["ABCDEFGHIJKLMNOPQRSTUVWXYZ",
0202                                  "abcdefghijklmnopqrstuvwxyz",
0203                                  "0123456789",
0204                                  "_.-"])
0205         result = urllib.quote(do_not_quote)
0206         self.assertEqual(do_not_quote, result,
0207                          "using quote(): %s != %s" % (do_not_quote, result))
0208         result = urllib.quote_plus(do_not_quote)
0209         self.assertEqual(do_not_quote, result,
0210                         "using quote_plus(): %s != %s" % (do_not_quote, result))
0211 
0212     def test_default_safe(self):
0213         # Test '/' is default value for 'safe' parameter
0214         self.assertEqual(urllib.quote.func_defaults[0], '/')
0215 
0216     def test_safe(self):
0217         # Test setting 'safe' parameter does what it should do
0218         quote_by_default = "<>"
0219         result = urllib.quote(quote_by_default, safe=quote_by_default)
0220         self.assertEqual(quote_by_default, result,
0221                          "using quote(): %s != %s" % (quote_by_default, result))
0222         result = urllib.quote_plus(quote_by_default, safe=quote_by_default)
0223         self.assertEqual(quote_by_default, result,
0224                          "using quote_plus(): %s != %s" %
0225                          (quote_by_default, result))
0226 
0227     def test_default_quoting(self):
0228         # Make sure all characters that should be quoted are by default sans
0229         # space (separate test for that).
0230         should_quote = [chr(num) for num in range(32)] # For 0x00 - 0x1F
0231         should_quote.append('<>#%"{}|\^[]`')
0232         should_quote.append(chr(127)) # For 0x7F
0233         should_quote = ''.join(should_quote)
0234         for char in should_quote:
0235             result = urllib.quote(char)
0236             self.assertEqual(hexescape(char), result,
0237                              "using quote(): %s should be escaped to %s, not %s" %
0238                              (char, hexescape(char), result))
0239             result = urllib.quote_plus(char)
0240             self.assertEqual(hexescape(char), result,
0241                              "using quote_plus(): "
0242                              "%s should be escapes to %s, not %s" %
0243                              (char, hexescape(char), result))
0244         del should_quote
0245         partial_quote = "ab[]cd"
0246         expected = "ab%5B%5Dcd"
0247         result = urllib.quote(partial_quote)
0248         self.assertEqual(expected, result,
0249                          "using quote(): %s != %s" % (expected, result))
0250         self.assertEqual(expected, result,
0251                          "using quote_plus(): %s != %s" % (expected, result))
0252 
0253     def test_quoting_space(self):
0254         # Make sure quote() and quote_plus() handle spaces as specified in
0255         # their unique way
0256         result = urllib.quote(' ')
0257         self.assertEqual(result, hexescape(' '),
0258                          "using quote(): %s != %s" % (result, hexescape(' ')))
0259         result = urllib.quote_plus(' ')
0260         self.assertEqual(result, '+',
0261                          "using quote_plus(): %s != +" % result)
0262         given = "a b cd e f"
0263         expect = given.replace(' ', hexescape(' '))
0264         result = urllib.quote(given)
0265         self.assertEqual(expect, result,
0266                          "using quote(): %s != %s" % (expect, result))
0267         expect = given.replace(' ', '+')
0268         result = urllib.quote_plus(given)
0269         self.assertEqual(expect, result,
0270                          "using quote_plus(): %s != %s" % (expect, result))
0271 
0272 class UnquotingTests(unittest.TestCase):
0273     """Tests for unquote() and unquote_plus()
0274 
0275     See the doc string for quoting_Tests for details on quoting and such.
0276 
0277     """
0278 
0279     def test_unquoting(self):
0280         # Make sure unquoting of all ASCII values works
0281         escape_list = []
0282         for num in range(128):
0283             given = hexescape(chr(num))
0284             expect = chr(num)
0285             result = urllib.unquote(given)
0286             self.assertEqual(expect, result,
0287                              "using unquote(): %s != %s" % (expect, result))
0288             result = urllib.unquote_plus(given)
0289             self.assertEqual(expect, result,
0290                              "using unquote_plus(): %s != %s" %
0291                              (expect, result))
0292             escape_list.append(given)
0293         escape_string = ''.join(escape_list)
0294         del escape_list
0295         result = urllib.unquote(escape_string)
0296         self.assertEqual(result.count('%'), 1,
0297                          "using quote(): not all characters escaped; %s" %
0298                          result)
0299         result = urllib.unquote(escape_string)
0300         self.assertEqual(result.count('%'), 1,
0301                          "using unquote(): not all characters escaped: "
0302                          "%s" % result)
0303 
0304     def test_unquoting_parts(self):
0305         # Make sure unquoting works when have non-quoted characters
0306         # interspersed
0307         given = 'ab%sd' % hexescape('c')
0308         expect = "abcd"
0309         result = urllib.unquote(given)
0310         self.assertEqual(expect, result,
0311                          "using quote(): %s != %s" % (expect, result))
0312         result = urllib.unquote_plus(given)
0313         self.assertEqual(expect, result,
0314                          "using unquote_plus(): %s != %s" % (expect, result))
0315 
0316     def test_unquoting_plus(self):
0317         # Test difference between unquote() and unquote_plus()
0318         given = "are+there+spaces..."
0319         expect = given
0320         result = urllib.unquote(given)
0321         self.assertEqual(expect, result,
0322                          "using unquote(): %s != %s" % (expect, result))
0323         expect = given.replace('+', ' ')
0324         result = urllib.unquote_plus(given)
0325         self.assertEqual(expect, result,
0326                          "using unquote_plus(): %s != %s" % (expect, result))
0327 
0328 class urlencode_Tests(unittest.TestCase):
0329     """Tests for urlencode()"""
0330 
0331     def help_inputtype(self, given, test_type):
0332         """Helper method for testing different input types.
0333 
0334         'given' must lead to only the pairs:
0335             * 1st, 1
0336             * 2nd, 2
0337             * 3rd, 3
0338 
0339         Test cannot assume anything about order.  Docs make no guarantee and
0340         have possible dictionary input.
0341 
0342         """
0343         expect_somewhere = ["1st=1", "2nd=2", "3rd=3"]
0344         result = urllib.urlencode(given)
0345         for expected in expect_somewhere:
0346             self.assert_(expected in result,
0347                          "testing %s: %s not found in %s" %
0348                          (test_type, expected, result))
0349         self.assertEqual(result.count('&'), 2,
0350                          "testing %s: expected 2 '&'s; got %s" %
0351                          (test_type, result.count('&')))
0352         amp_location = result.index('&')
0353         on_amp_left = result[amp_location - 1]
0354         on_amp_right = result[amp_location + 1]
0355         self.assert_(on_amp_left.isdigit() and on_amp_right.isdigit(),
0356                      "testing %s: '&' not located in proper place in %s" %
0357                      (test_type, result))
0358         self.assertEqual(len(result), (5 * 3) + 2, #5 chars per thing and amps
0359                          "testing %s: "
0360                          "unexpected number of characters: %s != %s" %
0361                          (test_type, len(result), (5 * 3) + 2))
0362 
0363     def test_using_mapping(self):
0364         # Test passing in a mapping object as an argument.
0365         self.help_inputtype({"1st":'1', "2nd":'2', "3rd":'3'},
0366                             "using dict as input type")
0367 
0368     def test_using_sequence(self):
0369         # Test passing in a sequence of two-item sequences as an argument.
0370         self.help_inputtype([('1st', '1'), ('2nd', '2'), ('3rd', '3')],
0371                             "using sequence of two-item tuples as input")
0372 
0373     def test_quoting(self):
0374         # Make sure keys and values are quoted using quote_plus()
0375         given = {"&":"="}
0376         expect = "%s=%s" % (hexescape('&'), hexescape('='))
0377         result = urllib.urlencode(given)
0378         self.assertEqual(expect, result)
0379         given = {"key name":"A bunch of pluses"}
0380         expect = "key+name=A+bunch+of+pluses"
0381         result = urllib.urlencode(given)
0382         self.assertEqual(expect, result)
0383 
0384     def test_doseq(self):
0385         # Test that passing True for 'doseq' parameter works correctly
0386         given = {'sequence':['1', '2', '3']}
0387         expect = "sequence=%s" % urllib.quote_plus(str(['1', '2', '3']))
0388         result = urllib.urlencode(given)
0389         self.assertEqual(expect, result)
0390         result = urllib.urlencode(given, True)
0391         for value in given["sequence"]:
0392             expect = "sequence=%s" % value
0393             self.assert_(expect in result,
0394                          "%s not found in %s" % (expect, result))
0395         self.assertEqual(result.count('&'), 2,
0396                          "Expected 2 '&'s, got %s" % result.count('&'))
0397 
0398 class Pathname_Tests(unittest.TestCase):
0399     """Test pathname2url() and url2pathname()"""
0400 
0401     def test_basic(self):
0402         # Make sure simple tests pass
0403         expected_path = os.path.join("parts", "of", "a", "path")
0404         expected_url = "parts/of/a/path"
0405         result = urllib.pathname2url(expected_path)
0406         self.assertEqual(expected_url, result,
0407                          "pathname2url() failed; %s != %s" %
0408                          (result, expected_url))
0409         result = urllib.url2pathname(expected_url)
0410         self.assertEqual(expected_path, result,
0411                          "url2pathame() failed; %s != %s" %
0412                          (result, expected_path))
0413 
0414     def test_quoting(self):
0415         # Test automatic quoting and unquoting works for pathnam2url() and
0416         # url2pathname() respectively
0417         given = os.path.join("needs", "quot=ing", "here")
0418         expect = "needs/%s/here" % urllib.quote("quot=ing")
0419         result = urllib.pathname2url(given)
0420         self.assertEqual(expect, result,
0421                          "pathname2url() failed; %s != %s" %
0422                          (expect, result))
0423         expect = given
0424         result = urllib.url2pathname(result)
0425         self.assertEqual(expect, result,
0426                          "url2pathname() failed; %s != %s" %
0427                          (expect, result))
0428         given = os.path.join("make sure", "using_quote")
0429         expect = "%s/using_quote" % urllib.quote("make sure")
0430         result = urllib.pathname2url(given)
0431         self.assertEqual(expect, result,
0432                          "pathname2url() failed; %s != %s" %
0433                          (expect, result))
0434         given = "make+sure/using_unquote"
0435         expect = os.path.join("make+sure", "using_unquote")
0436         result = urllib.url2pathname(given)
0437         self.assertEqual(expect, result,
0438                          "url2pathname() failed; %s != %s" %
0439                          (expect, result))
0440 
0441 
0442 
0443 def test_main():
0444     test_support.run_unittest(
0445         urlopen_FileTests,
0446         urlopen_HttpTests,
0447         urlretrieve_FileTests,
0448         QuotingTests,
0449         UnquotingTests,
0450         urlencode_Tests,
0451         Pathname_Tests
0452     )
0453 
0454 
0455 
0456 if __name__ == '__main__':
0457     test_main()
0458 

Generated by PyXR 0.9.4
SourceForge.net Logo