Home | History | Annotate | Download | only in test
      1 """Regresssion tests for urllib"""
      2 
      3 import urllib
      4 import httplib
      5 import unittest
      6 from test import test_support
      7 import os
      8 import sys
      9 import mimetools
     10 import tempfile
     11 import StringIO
     12 
     13 def hexescape(char):
     14     """Escape char as RFC 2396 specifies"""
     15     hex_repr = hex(ord(char))[2:].upper()
     16     if len(hex_repr) == 1:
     17         hex_repr = "0%s" % hex_repr
     18     return "%" + hex_repr
     19 
     20 class urlopen_FileTests(unittest.TestCase):
     21     """Test urlopen() opening a temporary file.
     22 
     23     Try to test as much functionality as possible so as to cut down on reliance
     24     on connecting to the Net for testing.
     25 
     26     """
     27 
     28     def setUp(self):
     29         """Setup of a temp file to use for testing"""
     30         self.text = "test_urllib: %s\n" % self.__class__.__name__
     31         FILE = file(test_support.TESTFN, 'wb')
     32         try:
     33             FILE.write(self.text)
     34         finally:
     35             FILE.close()
     36         self.pathname = test_support.TESTFN
     37         self.returned_obj = urllib.urlopen("file:%s" % self.pathname)
     38 
     39     def tearDown(self):
     40         """Shut down the open object"""
     41         self.returned_obj.close()
     42         os.remove(test_support.TESTFN)
     43 
     44     def test_interface(self):
     45         # Make sure object returned by urlopen() has the specified methods

     46         for attr in ("read", "readline", "readlines", "fileno",
     47                      "close", "info", "geturl", "getcode", "__iter__"):
     48             self.assertTrue(hasattr(self.returned_obj, attr),
     49                          "object returned by urlopen() lacks %s attribute" %
     50                          attr)
     51 
     52     def test_read(self):
     53         self.assertEqual(self.text, self.returned_obj.read())
     54 
     55     def test_readline(self):
     56         self.assertEqual(self.text, self.returned_obj.readline())
     57         self.assertEqual('', self.returned_obj.readline(),
     58                          "calling readline() after exhausting the file did not"
     59                          " return an empty string")
     60 
     61     def test_readlines(self):
     62         lines_list = self.returned_obj.readlines()
     63         self.assertEqual(len(lines_list), 1,
     64                          "readlines() returned the wrong number of lines")
     65         self.assertEqual(lines_list[0], self.text,
     66                          "readlines() returned improper text")
     67 
     68     def test_fileno(self):
     69         file_num = self.returned_obj.fileno()
     70         self.assertIsInstance(file_num, int, "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")
     74 
     75     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()
     79 
     80     def test_info(self):
     81         self.assertIsInstance(self.returned_obj.info(), mimetools.Message)
     82 
     83     def test_geturl(self):
     84         self.assertEqual(self.returned_obj.geturl(), self.pathname)
     85 
     86     def test_getcode(self):
     87         self.assertEqual(self.returned_obj.getcode(), None)
     88 
     89     def test_iter(self):
     90         # Test iterator

     91         # Don't need to count number of iterations since test would fail the

     92         # instant it returned anything beyond the first line from the

     93         # comparison

     94         for line in self.returned_obj.__iter__():
     95             self.assertEqual(line, self.text)
     96 
     97 class ProxyTests(unittest.TestCase):
     98 
     99     def setUp(self):
    100         # Records changes to env vars

    101         self.env = test_support.EnvironmentVarGuard()
    102         # Delete all proxy related env vars

    103         for k in os.environ.keys():
    104             if 'proxy' in k.lower():
    105                 self.env.unset(k)
    106 
    107     def tearDown(self):
    108         # Restore all proxy related env vars

    109         self.env.__exit__()
    110         del self.env
    111 
    112     def test_getproxies_environment_keep_no_proxies(self):
    113         self.env.set('NO_PROXY', 'localhost')
    114         proxies = urllib.getproxies_environment()
    115         # getproxies_environment use lowered case truncated (no '_proxy') keys

    116         self.assertEqual('localhost', proxies['no'])
    117 
    118 
    119 class urlopen_HttpTests(unittest.TestCase):
    120     """Test urlopen() opening a fake http connection."""
    121 
    122     def fakehttp(self, fakedata):
    123         class FakeSocket(StringIO.StringIO):
    124             def sendall(self, str): pass
    125             def makefile(self, mode, name): return self
    126             def read(self, amt=None):
    127                 if self.closed: return ''
    128                 return StringIO.StringIO.read(self, amt)
    129             def readline(self, length=None):
    130                 if self.closed: return ''
    131                 return StringIO.StringIO.readline(self, length)
    132         class FakeHTTPConnection(httplib.HTTPConnection):
    133             def connect(self):
    134                 self.sock = FakeSocket(fakedata)
    135         assert httplib.HTTP._connection_class == httplib.HTTPConnection
    136         httplib.HTTP._connection_class = FakeHTTPConnection
    137 
    138     def unfakehttp(self):
    139         httplib.HTTP._connection_class = httplib.HTTPConnection
    140 
    141     def test_read(self):
    142         self.fakehttp('Hello!')
    143         try:
    144             fp = urllib.urlopen("http://python.org/")
    145             self.assertEqual(fp.readline(), 'Hello!')
    146             self.assertEqual(fp.readline(), '')
    147             self.assertEqual(fp.geturl(), 'http://python.org/')
    148             self.assertEqual(fp.getcode(), 200)
    149         finally:
    150             self.unfakehttp()
    151 
    152     def test_url_fragment(self):
    153         # Issue #11703: geturl() omits fragments in the original URL.

    154         url = 'http://docs.python.org/library/urllib.html#OK'
    155         self.fakehttp('Hello!')
    156         try:
    157             fp = urllib.urlopen(url)
    158             self.assertEqual(fp.geturl(), url)
    159         finally:
    160             self.unfakehttp()
    161 
    162     def test_read_bogus(self):
    163         # urlopen() should raise IOError for many error codes.

    164         self.fakehttp('''HTTP/1.1 401 Authentication Required
    165 Date: Wed, 02 Jan 2008 03:03:54 GMT
    166 Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
    167 Connection: close
    168 Content-Type: text/html; charset=iso-8859-1
    169 ''')
    170         try:
    171             self.assertRaises(IOError, urllib.urlopen, "http://python.org/")
    172         finally:
    173             self.unfakehttp()
    174 
    175     def test_invalid_redirect(self):
    176         # urlopen() should raise IOError for many error codes.

    177         self.fakehttp("""HTTP/1.1 302 Found
    178 Date: Wed, 02 Jan 2008 03:03:54 GMT
    179 Server: Apache/1.3.33 (Debian GNU/Linux) mod_ssl/2.8.22 OpenSSL/0.9.7e
    180 Location: file:README
    181 Connection: close
    182 Content-Type: text/html; charset=iso-8859-1
    183 """)
    184         try:
    185             self.assertRaises(IOError, urllib.urlopen, "http://python.org/")
    186         finally:
    187             self.unfakehttp()
    188 
    189     def test_empty_socket(self):
    190         # urlopen() raises IOError if the underlying socket does not send any

    191         # data. (#1680230)

    192         self.fakehttp('')
    193         try:
    194             self.assertRaises(IOError, urllib.urlopen, 'http://something')
    195         finally:
    196             self.unfakehttp()
    197 
    198 class urlretrieve_FileTests(unittest.TestCase):
    199     """Test urllib.urlretrieve() on local files"""
    200 
    201     def setUp(self):
    202         # Create a list of temporary files. Each item in the list is a file

    203         # name (absolute path or relative to the current working directory).

    204         # All files in this list will be deleted in the tearDown method. Note,

    205         # this only helps to makes sure temporary files get deleted, but it

    206         # does nothing about trying to close files that may still be open. It

    207         # is the responsibility of the developer to properly close files even

    208         # when exceptional conditions occur.

    209         self.tempFiles = []
    210 
    211         # Create a temporary file.

    212         self.registerFileForCleanUp(test_support.TESTFN)
    213         self.text = 'testing urllib.urlretrieve'
    214         try:
    215             FILE = file(test_support.TESTFN, 'wb')
    216             FILE.write(self.text)
    217             FILE.close()
    218         finally:
    219             try: FILE.close()
    220             except: pass
    221 
    222     def tearDown(self):
    223         # Delete the temporary files.

    224         for each in self.tempFiles:
    225             try: os.remove(each)
    226             except: pass
    227 
    228     def constructLocalFileUrl(self, filePath):
    229         return "file://%s" % urllib.pathname2url(os.path.abspath(filePath))
    230 
    231     def createNewTempFile(self, data=""):
    232         """Creates a new temporary file containing the specified data,
    233         registers the file for deletion during the test fixture tear down, and
    234         returns the absolute path of the file."""
    235 
    236         newFd, newFilePath = tempfile.mkstemp()
    237         try:
    238             self.registerFileForCleanUp(newFilePath)
    239             newFile = os.fdopen(newFd, "wb")
    240             newFile.write(data)
    241             newFile.close()
    242         finally:
    243             try: newFile.close()
    244             except: pass
    245         return newFilePath
    246 
    247     def registerFileForCleanUp(self, fileName):
    248         self.tempFiles.append(fileName)
    249 
    250     def test_basic(self):
    251         # Make sure that a local file just gets its own location returned and

    252         # a headers value is returned.

    253         result = urllib.urlretrieve("file:%s" % test_support.TESTFN)
    254         self.assertEqual(result[0], test_support.TESTFN)
    255         self.assertIsInstance(result[1], mimetools.Message,
    256                               "did not get a mimetools.Message instance as "
    257                               "second returned value")
    258 
    259     def test_copy(self):
    260         # Test that setting the filename argument works.

    261         second_temp = "%s.2" % test_support.TESTFN
    262         self.registerFileForCleanUp(second_temp)
    263         result = urllib.urlretrieve(self.constructLocalFileUrl(
    264             test_support.TESTFN), second_temp)
    265         self.assertEqual(second_temp, result[0])
    266         self.assertTrue(os.path.exists(second_temp), "copy of the file was not "
    267                                                   "made")
    268         FILE = file(second_temp, 'rb')
    269         try:
    270             text = FILE.read()
    271             FILE.close()
    272         finally:
    273             try: FILE.close()
    274             except: pass
    275         self.assertEqual(self.text, text)
    276 
    277     def test_reporthook(self):
    278         # Make sure that the reporthook works.

    279         def hooktester(count, block_size, total_size, count_holder=[0]):
    280             self.assertIsInstance(count, int)
    281             self.assertIsInstance(block_size, int)
    282             self.assertIsInstance(total_size, int)
    283             self.assertEqual(count, count_holder[0])
    284             count_holder[0] = count_holder[0] + 1
    285         second_temp = "%s.2" % test_support.TESTFN
    286         self.registerFileForCleanUp(second_temp)
    287         urllib.urlretrieve(self.constructLocalFileUrl(test_support.TESTFN),
    288             second_temp, hooktester)
    289 
    290     def test_reporthook_0_bytes(self):
    291         # Test on zero length file. Should call reporthook only 1 time.

    292         report = []
    293         def hooktester(count, block_size, total_size, _report=report):
    294             _report.append((count, block_size, total_size))
    295         srcFileName = self.createNewTempFile()
    296         urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
    297             test_support.TESTFN, hooktester)
    298         self.assertEqual(len(report), 1)
    299         self.assertEqual(report[0][2], 0)
    300 
    301     def test_reporthook_5_bytes(self):
    302         # Test on 5 byte file. Should call reporthook only 2 times (once when

    303         # the "network connection" is established and once when the block is

    304         # read). Since the block size is 8192 bytes, only one block read is

    305         # required to read the entire file.

    306         report = []
    307         def hooktester(count, block_size, total_size, _report=report):
    308             _report.append((count, block_size, total_size))
    309         srcFileName = self.createNewTempFile("x" * 5)
    310         urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
    311             test_support.TESTFN, hooktester)
    312         self.assertEqual(len(report), 2)
    313         self.assertEqual(report[0][1], 8192)
    314         self.assertEqual(report[0][2], 5)
    315 
    316     def test_reporthook_8193_bytes(self):
    317         # Test on 8193 byte file. Should call reporthook only 3 times (once

    318         # when the "network connection" is established, once for the next 8192

    319         # bytes, and once for the last byte).

    320         report = []
    321         def hooktester(count, block_size, total_size, _report=report):
    322             _report.append((count, block_size, total_size))
    323         srcFileName = self.createNewTempFile("x" * 8193)
    324         urllib.urlretrieve(self.constructLocalFileUrl(srcFileName),
    325             test_support.TESTFN, hooktester)
    326         self.assertEqual(len(report), 3)
    327         self.assertEqual(report[0][1], 8192)
    328         self.assertEqual(report[0][2], 8193)
    329 
    330 class QuotingTests(unittest.TestCase):
    331     """Tests for urllib.quote() and urllib.quote_plus()
    332 
    333     According to RFC 2396 ("Uniform Resource Identifiers), to escape a
    334     character you write it as '%' + <2 character US-ASCII hex value>.  The Python
    335     code of ``'%' + hex(ord(<character>))[2:]`` escapes a character properly.
    336     Case does not matter on the hex letters.
    337 
    338     The various character sets specified are:
    339 
    340     Reserved characters : ";/?:@&=+$,"
    341         Have special meaning in URIs and must be escaped if not being used for
    342         their special meaning
    343     Data characters : letters, digits, and "-_.!~*'()"
    344         Unreserved and do not need to be escaped; can be, though, if desired
    345     Control characters : 0x00 - 0x1F, 0x7F
    346         Have no use in URIs so must be escaped
    347     space : 0x20
    348         Must be escaped
    349     Delimiters : '<>#%"'
    350         Must be escaped
    351     Unwise : "{}|\^[]`"
    352         Must be escaped
    353 
    354     """
    355 
    356     def test_never_quote(self):
    357         # Make sure quote() does not quote letters, digits, and "_,.-"

    358         do_not_quote = '' .join(["ABCDEFGHIJKLMNOPQRSTUVWXYZ",
    359                                  "abcdefghijklmnopqrstuvwxyz",
    360                                  "0123456789",
    361                                  "_.-"])
    362         result = urllib.quote(do_not_quote)
    363         self.assertEqual(do_not_quote, result,
    364                          "using quote(): %s != %s" % (do_not_quote, result))
    365         result = urllib.quote_plus(do_not_quote)
    366         self.assertEqual(do_not_quote, result,
    367                         "using quote_plus(): %s != %s" % (do_not_quote, result))
    368 
    369     def test_default_safe(self):
    370         # Test '/' is default value for 'safe' parameter

    371         self.assertEqual(urllib.quote.func_defaults[0], '/')
    372 
    373     def test_safe(self):
    374         # Test setting 'safe' parameter does what it should do

    375         quote_by_default = "<>"
    376         result = urllib.quote(quote_by_default, safe=quote_by_default)
    377         self.assertEqual(quote_by_default, result,
    378                          "using quote(): %s != %s" % (quote_by_default, result))
    379         result = urllib.quote_plus(quote_by_default, safe=quote_by_default)
    380         self.assertEqual(quote_by_default, result,
    381                          "using quote_plus(): %s != %s" %
    382                          (quote_by_default, result))
    383 
    384     def test_default_quoting(self):
    385         # Make sure all characters that should be quoted are by default sans

    386         # space (separate test for that).

    387         should_quote = [chr(num) for num in range(32)] # For 0x00 - 0x1F

    388         should_quote.append('<>#%"{}|\^[]`')
    389         should_quote.append(chr(127)) # For 0x7F

    390         should_quote = ''.join(should_quote)
    391         for char in should_quote:
    392             result = urllib.quote(char)
    393             self.assertEqual(hexescape(char), result,
    394                              "using quote(): %s should be escaped to %s, not %s" %
    395                              (char, hexescape(char), result))
    396             result = urllib.quote_plus(char)
    397             self.assertEqual(hexescape(char), result,
    398                              "using quote_plus(): "
    399                              "%s should be escapes to %s, not %s" %
    400                              (char, hexescape(char), result))
    401         del should_quote
    402         partial_quote = "ab[]cd"
    403         expected = "ab%5B%5Dcd"
    404         result = urllib.quote(partial_quote)
    405         self.assertEqual(expected, result,
    406                          "using quote(): %s != %s" % (expected, result))
    407         self.assertEqual(expected, result,
    408                          "using quote_plus(): %s != %s" % (expected, result))
    409         self.assertRaises(TypeError, urllib.quote, None)
    410 
    411     def test_quoting_space(self):
    412         # Make sure quote() and quote_plus() handle spaces as specified in

    413         # their unique way

    414         result = urllib.quote(' ')
    415         self.assertEqual(result, hexescape(' '),
    416                          "using quote(): %s != %s" % (result, hexescape(' ')))
    417         result = urllib.quote_plus(' ')
    418         self.assertEqual(result, '+',
    419                          "using quote_plus(): %s != +" % result)
    420         given = "a b cd e f"
    421         expect = given.replace(' ', hexescape(' '))
    422         result = urllib.quote(given)
    423         self.assertEqual(expect, result,
    424                          "using quote(): %s != %s" % (expect, result))
    425         expect = given.replace(' ', '+')
    426         result = urllib.quote_plus(given)
    427         self.assertEqual(expect, result,
    428                          "using quote_plus(): %s != %s" % (expect, result))
    429 
    430     def test_quoting_plus(self):
    431         self.assertEqual(urllib.quote_plus('alpha+beta gamma'),
    432                          'alpha%2Bbeta+gamma')
    433         self.assertEqual(urllib.quote_plus('alpha+beta gamma', '+'),
    434                          'alpha+beta+gamma')
    435 
    436 class UnquotingTests(unittest.TestCase):
    437     """Tests for unquote() and unquote_plus()
    438 
    439     See the doc string for quoting_Tests for details on quoting and such.
    440 
    441     """
    442 
    443     def test_unquoting(self):
    444         # Make sure unquoting of all ASCII values works

    445         escape_list = []
    446         for num in range(128):
    447             given = hexescape(chr(num))
    448             expect = chr(num)
    449             result = urllib.unquote(given)
    450             self.assertEqual(expect, result,
    451                              "using unquote(): %s != %s" % (expect, result))
    452             result = urllib.unquote_plus(given)
    453             self.assertEqual(expect, result,
    454                              "using unquote_plus(): %s != %s" %
    455                              (expect, result))
    456             escape_list.append(given)
    457         escape_string = ''.join(escape_list)
    458         del escape_list
    459         result = urllib.unquote(escape_string)
    460         self.assertEqual(result.count('%'), 1,
    461                          "using quote(): not all characters escaped; %s" %
    462                          result)
    463         result = urllib.unquote(escape_string)
    464         self.assertEqual(result.count('%'), 1,
    465                          "using unquote(): not all characters escaped: "
    466                          "%s" % result)
    467 
    468     def test_unquoting_badpercent(self):
    469         # Test unquoting on bad percent-escapes

    470         given = '%xab'
    471         expect = given
    472         result = urllib.unquote(given)
    473         self.assertEqual(expect, result, "using unquote(): %r != %r"
    474                          % (expect, result))
    475         given = '%x'
    476         expect = given
    477         result = urllib.unquote(given)
    478         self.assertEqual(expect, result, "using unquote(): %r != %r"
    479                          % (expect, result))
    480         given = '%'
    481         expect = given
    482         result = urllib.unquote(given)
    483         self.assertEqual(expect, result, "using unquote(): %r != %r"
    484                          % (expect, result))
    485 
    486     def test_unquoting_mixed_case(self):
    487         # Test unquoting on mixed-case hex digits in the percent-escapes

    488         given = '%Ab%eA'
    489         expect = '\xab\xea'
    490         result = urllib.unquote(given)
    491         self.assertEqual(expect, result, "using unquote(): %r != %r"
    492                          % (expect, result))
    493 
    494     def test_unquoting_parts(self):
    495         # Make sure unquoting works when have non-quoted characters

    496         # interspersed

    497         given = 'ab%sd' % hexescape('c')
    498         expect = "abcd"
    499         result = urllib.unquote(given)
    500         self.assertEqual(expect, result,
    501                          "using quote(): %s != %s" % (expect, result))
    502         result = urllib.unquote_plus(given)
    503         self.assertEqual(expect, result,
    504                          "using unquote_plus(): %s != %s" % (expect, result))
    505 
    506     def test_unquoting_plus(self):
    507         # Test difference between unquote() and unquote_plus()

    508         given = "are+there+spaces..."
    509         expect = given
    510         result = urllib.unquote(given)
    511         self.assertEqual(expect, result,
    512                          "using unquote(): %s != %s" % (expect, result))
    513         expect = given.replace('+', ' ')
    514         result = urllib.unquote_plus(given)
    515         self.assertEqual(expect, result,
    516                          "using unquote_plus(): %s != %s" % (expect, result))
    517 
    518     def test_unquote_with_unicode(self):
    519         r = urllib.unquote(u'br%C3%BCckner_sapporo_20050930.doc')
    520         self.assertEqual(r, u'br\xc3\xbcckner_sapporo_20050930.doc')
    521 
    522 class urlencode_Tests(unittest.TestCase):
    523     """Tests for urlencode()"""
    524 
    525     def help_inputtype(self, given, test_type):
    526         """Helper method for testing different input types.
    527 
    528         'given' must lead to only the pairs:
    529             * 1st, 1
    530             * 2nd, 2
    531             * 3rd, 3
    532 
    533         Test cannot assume anything about order.  Docs make no guarantee and
    534         have possible dictionary input.
    535 
    536         """
    537         expect_somewhere = ["1st=1", "2nd=2", "3rd=3"]
    538         result = urllib.urlencode(given)
    539         for expected in expect_somewhere:
    540             self.assertIn(expected, result,
    541                          "testing %s: %s not found in %s" %
    542                          (test_type, expected, result))
    543         self.assertEqual(result.count('&'), 2,
    544                          "testing %s: expected 2 '&'s; got %s" %
    545                          (test_type, result.count('&')))
    546         amp_location = result.index('&')
    547         on_amp_left = result[amp_location - 1]
    548         on_amp_right = result[amp_location + 1]
    549         self.assertTrue(on_amp_left.isdigit() and on_amp_right.isdigit(),
    550                      "testing %s: '&' not located in proper place in %s" %
    551                      (test_type, result))
    552         self.assertEqual(len(result), (5 * 3) + 2, #5 chars per thing and amps

    553                          "testing %s: "
    554                          "unexpected number of characters: %s != %s" %
    555                          (test_type, len(result), (5 * 3) + 2))
    556 
    557     def test_using_mapping(self):
    558         # Test passing in a mapping object as an argument.

    559         self.help_inputtype({"1st":'1', "2nd":'2', "3rd":'3'},
    560                             "using dict as input type")
    561 
    562     def test_using_sequence(self):
    563         # Test passing in a sequence of two-item sequences as an argument.

    564         self.help_inputtype([('1st', '1'), ('2nd', '2'), ('3rd', '3')],
    565                             "using sequence of two-item tuples as input")
    566 
    567     def test_quoting(self):
    568         # Make sure keys and values are quoted using quote_plus()

    569         given = {"&":"="}
    570         expect = "%s=%s" % (hexescape('&'), hexescape('='))
    571         result = urllib.urlencode(given)
    572         self.assertEqual(expect, result)
    573         given = {"key name":"A bunch of pluses"}
    574         expect = "key+name=A+bunch+of+pluses"
    575         result = urllib.urlencode(given)
    576         self.assertEqual(expect, result)
    577 
    578     def test_doseq(self):
    579         # Test that passing True for 'doseq' parameter works correctly

    580         given = {'sequence':['1', '2', '3']}
    581         expect = "sequence=%s" % urllib.quote_plus(str(['1', '2', '3']))
    582         result = urllib.urlencode(given)
    583         self.assertEqual(expect, result)
    584         result = urllib.urlencode(given, True)
    585         for value in given["sequence"]:
    586             expect = "sequence=%s" % value
    587             self.assertIn(expect, result)
    588         self.assertEqual(result.count('&'), 2,
    589                          "Expected 2 '&'s, got %s" % result.count('&'))
    590 
    591 class Pathname_Tests(unittest.TestCase):
    592     """Test pathname2url() and url2pathname()"""
    593 
    594     def test_basic(self):
    595         # Make sure simple tests pass

    596         expected_path = os.path.join("parts", "of", "a", "path")
    597         expected_url = "parts/of/a/path"
    598         result = urllib.pathname2url(expected_path)
    599         self.assertEqual(expected_url, result,
    600                          "pathname2url() failed; %s != %s" %
    601                          (result, expected_url))
    602         result = urllib.url2pathname(expected_url)
    603         self.assertEqual(expected_path, result,
    604                          "url2pathame() failed; %s != %s" %
    605                          (result, expected_path))
    606 
    607     def test_quoting(self):
    608         # Test automatic quoting and unquoting works for pathnam2url() and

    609         # url2pathname() respectively

    610         given = os.path.join("needs", "quot=ing", "here")
    611         expect = "needs/%s/here" % urllib.quote("quot=ing")
    612         result = urllib.pathname2url(given)
    613         self.assertEqual(expect, result,
    614                          "pathname2url() failed; %s != %s" %
    615                          (expect, result))
    616         expect = given
    617         result = urllib.url2pathname(result)
    618         self.assertEqual(expect, result,
    619                          "url2pathname() failed; %s != %s" %
    620                          (expect, result))
    621         given = os.path.join("make sure", "using_quote")
    622         expect = "%s/using_quote" % urllib.quote("make sure")
    623         result = urllib.pathname2url(given)
    624         self.assertEqual(expect, result,
    625                          "pathname2url() failed; %s != %s" %
    626                          (expect, result))
    627         given = "make+sure/using_unquote"
    628         expect = os.path.join("make+sure", "using_unquote")
    629         result = urllib.url2pathname(given)
    630         self.assertEqual(expect, result,
    631                          "url2pathname() failed; %s != %s" %
    632                          (expect, result))
    633 
    634     @unittest.skipUnless(sys.platform == 'win32',
    635                          'test specific to the nturl2path library')
    636     def test_ntpath(self):
    637         given = ('/C:/', '///C:/', '/C|//')
    638         expect = 'C:\\'
    639         for url in given:
    640             result = urllib.url2pathname(url)
    641             self.assertEqual(expect, result,
    642                              'nturl2path.url2pathname() failed; %s != %s' %
    643                              (expect, result))
    644         given = '///C|/path'
    645         expect = 'C:\\path'
    646         result = urllib.url2pathname(given)
    647         self.assertEqual(expect, result,
    648                          'nturl2path.url2pathname() failed; %s != %s' %
    649                          (expect, result))
    650 
    651 class Utility_Tests(unittest.TestCase):
    652     """Testcase to test the various utility functions in the urllib."""
    653 
    654     def test_splitpasswd(self):
    655         """Some of the password examples are not sensible, but it is added to
    656         confirming to RFC2617 and addressing issue4675.
    657         """
    658         self.assertEqual(('user', 'ab'),urllib.splitpasswd('user:ab'))
    659         self.assertEqual(('user', 'a\nb'),urllib.splitpasswd('user:a\nb'))
    660         self.assertEqual(('user', 'a\tb'),urllib.splitpasswd('user:a\tb'))
    661         self.assertEqual(('user', 'a\rb'),urllib.splitpasswd('user:a\rb'))
    662         self.assertEqual(('user', 'a\fb'),urllib.splitpasswd('user:a\fb'))
    663         self.assertEqual(('user', 'a\vb'),urllib.splitpasswd('user:a\vb'))
    664         self.assertEqual(('user', 'a:b'),urllib.splitpasswd('user:a:b'))
    665 
    666 
    667 class URLopener_Tests(unittest.TestCase):
    668     """Testcase to test the open method of URLopener class."""
    669 
    670     def test_quoted_open(self):
    671         class DummyURLopener(urllib.URLopener):
    672             def open_spam(self, url):
    673                 return url
    674 
    675         self.assertEqual(DummyURLopener().open(
    676             'spam://example/ /'),'//example/%20/')
    677 
    678         # test the safe characters are not quoted by urlopen
    679         self.assertEqual(DummyURLopener().open(
    680             "spam://c:|windows%/:=&?~#+!$,;'@()*[]|/path/"),
    681             "//c:|windows%/:=&?~#+!$,;'@()*[]|/path/")

    682 
    683 
    684 # Just commented them out.

    685 # Can't really tell why keep failing in windows and sparc.

    686 # Everywhere else they work ok, but on those machines, sometimes

    687 # fail in one of the tests, sometimes in other. I have a linux, and

    688 # the tests go ok.

    689 # If anybody has one of the problematic enviroments, please help!

    690 # .   Facundo

    691 #

    692 # def server(evt):

    693 #     import socket, time

    694 #     serv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    695 #     serv.settimeout(3)

    696 #     serv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    697 #     serv.bind(("", 9093))

    698 #     serv.listen(5)

    699 #     try:

    700 #         conn, addr = serv.accept()

    701 #         conn.send("1 Hola mundo\n")

    702 #         cantdata = 0

    703 #         while cantdata < 13:

    704 #             data = conn.recv(13-cantdata)

    705 #             cantdata += len(data)

    706 #             time.sleep(.3)

    707 #         conn.send("2 No more lines\n")

    708 #         conn.close()

    709 #     except socket.timeout:

    710 #         pass

    711 #     finally:

    712 #         serv.close()

    713 #         evt.set()

    714 #

    715 # class FTPWrapperTests(unittest.TestCase):

    716 #

    717 #     def setUp(self):

    718 #         import ftplib, time, threading

    719 #         ftplib.FTP.port = 9093

    720 #         self.evt = threading.Event()

    721 #         threading.Thread(target=server, args=(self.evt,)).start()

    722 #         time.sleep(.1)

    723 #

    724 #     def tearDown(self):

    725 #         self.evt.wait()

    726 #

    727 #     def testBasic(self):

    728 #         # connects

    729 #         ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])

    730 #         ftp.close()

    731 #

    732 #     def testTimeoutNone(self):

    733 #         # global default timeout is ignored

    734 #         import socket

    735 #         self.assertTrue(socket.getdefaulttimeout() is None)

    736 #         socket.setdefaulttimeout(30)

    737 #         try:

    738 #             ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])

    739 #         finally:

    740 #             socket.setdefaulttimeout(None)

    741 #         self.assertEqual(ftp.ftp.sock.gettimeout(), 30)

    742 #         ftp.close()

    743 #

    744 #     def testTimeoutDefault(self):

    745 #         # global default timeout is used

    746 #         import socket

    747 #         self.assertTrue(socket.getdefaulttimeout() is None)

    748 #         socket.setdefaulttimeout(30)

    749 #         try:

    750 #             ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [])

    751 #         finally:

    752 #             socket.setdefaulttimeout(None)

    753 #         self.assertEqual(ftp.ftp.sock.gettimeout(), 30)

    754 #         ftp.close()

    755 #

    756 #     def testTimeoutValue(self):

    757 #         ftp = urllib.ftpwrapper("myuser", "mypass", "localhost", 9093, [],

    758 #                                 timeout=30)

    759 #         self.assertEqual(ftp.ftp.sock.gettimeout(), 30)

    760 #         ftp.close()

    761 
    762 
    763 
    764 def test_main():
    765     import warnings
    766     with warnings.catch_warnings():
    767         warnings.filterwarnings('ignore', ".*urllib\.urlopen.*Python 3.0",
    768                                 DeprecationWarning)
    769         test_support.run_unittest(
    770             urlopen_FileTests,
    771             urlopen_HttpTests,
    772             urlretrieve_FileTests,
    773             ProxyTests,
    774             QuotingTests,
    775             UnquotingTests,
    776             urlencode_Tests,
    777             Pathname_Tests,
    778             Utility_Tests,
    779             URLopener_Tests,
    780             #FTPWrapperTests,

    781         )
    782 
    783 
    784 
    785 if __name__ == '__main__':
    786     test_main()
    787