Package lxml :: Package tests :: Module test_io

[hide private]
[frames] | no frames]

# Source Code for Module lxml.tests.test_io

      1  # -*- coding: utf-8 -*-
      2
      3  """
      4  IO test cases that apply to both etree and ElementTree
      5  """
      6
      7  import unittest
      8  import tempfile, gzip, os, os.path, sys, gc, shutil
      9
     10  this_dir = os.path.dirname(__file__)
     11  if this_dir not in sys.path:
     12      sys.path.insert(0, this_dir) # needed for Py3
     13
     14  from common_imports import etree, ElementTree, fileInTestDir, _str, _bytes
     15  from common_imports import SillyFileLike, LargeFileLike, HelperTestCase
     16
     17 -class IOTestCaseBase(HelperTestCase):
     18      """(c)ElementTree compatibility for IO functions/methods
     19      """
     20      etree = None
     21
     22 -    def setUp(self):
     23          """Setting up a minimal tree
     24          """
     25          self.root = self.etree.Element('a')
     26          self.root_str = self.etree.tostring(self.root)
     27          self.tree = self.etree.ElementTree(self.root)
     28          self._temp_dir = tempfile.mkdtemp()
     29
     30 -    def tearDown(self):
     31          gc.collect()
     32          shutil.rmtree(self._temp_dir)
     33
     34 -    def getTestFilePath(self, name):
     35          return os.path.join(self._temp_dir, name)
     36
     37 -    def buildNodes(self, element, children, depth):
     38          Element = self.etree.Element
     39
     40          if depth == 0:
     41              return
     42          for i in range(children):
     43              new_element = Element('element_%s_%s' % (depth, i))
     44              self.buildNodes(new_element, children, depth - 1)
     45              element.append(new_element)
     46
     47 -    def test_tree_io(self):
     48          Element = self.etree.Element
     49          ElementTree = self.etree.ElementTree
     50
     51          element = Element('top')
     52          element.text = _str("qwrtioüöä\uAABB")
     53          tree = ElementTree(element)
     54          self.buildNodes(element, 10, 3)
     55          f = open(self.getTestFilePath('testdump.xml'), 'wb')
     56          tree.write(f, encoding='UTF-8')
     57          f.close()
     58          f = open(self.getTestFilePath('testdump.xml'), 'rb')
     59          tree = ElementTree(file=f)
     60          f.close()
     61          f = open(self.getTestFilePath('testdump2.xml'), 'wb')
     62          tree.write(f, encoding='UTF-8')
     63          f.close()
     64          f = open(self.getTestFilePath('testdump.xml'), 'rb')
     65          data1 = f.read()
     66          f.close()
     67          f = open(self.getTestFilePath('testdump2.xml'), 'rb')
     68          data2 = f.read()
     69          f.close()
     70          self.assertEquals(data1, data2)
     71
     72 -    def test_tree_io_latin1(self):
     73          Element = self.etree.Element
     74          ElementTree = self.etree.ElementTree
     75
     76          element = Element('top')
     77          element.text = _str("qwrtioüöäßÃ¡")
     78          tree = ElementTree(element)
     79          self.buildNodes(element, 10, 3)
     80          f = open(self.getTestFilePath('testdump.xml'), 'wb')
     81          tree.write(f, encoding='iso-8859-1')
     82          f.close()
     83          f = open(self.getTestFilePath('testdump.xml'), 'rb')
     84          tree = ElementTree(file=f)
     85          f.close()
     86          f = open(self.getTestFilePath('testdump2.xml'), 'wb')
     87          tree.write(f, encoding='iso-8859-1')
     88          f.close()
     89          f = open(self.getTestFilePath('testdump.xml'), 'rb')
     90          data1 = f.read()
     91          f.close()
     92          f = open(self.getTestFilePath('testdump2.xml'), 'rb')
     93          data2 = f.read()
     94          f.close()
     95          self.assertEquals(data1, data2)
     96
     97 -    def test_write_filename(self):
     98          # (c)ElementTree  supports filename strings as write argument
     99
    100          handle, filename = tempfile.mkstemp(suffix=".xml")
    101          self.tree.write(filename)
    102          try:
    103              self.assertEqual(open(filename, 'rb').read().replace(_bytes('\n'), _bytes('')),
    104                               self.root_str)
    105          finally:
    106              os.close(handle)
    107              os.remove(filename)
    108
    109 -    def test_write_invalid_filename(self):
    110          filename = os.path.join(
    111              os.path.join('hopefullynonexistingpathname'),
    112              'invalid_file.xml')
    113          try:
    114              self.tree.write(filename)
    115          except IOError:
    116              pass
    117          else:
    118              self.assertTrue(
    119                  False, "writing to an invalid file path should fail")
    120
    121 -    def test_module_parse_gzipobject(self):
    122          # (c)ElementTree supports gzip instance as parse argument
    123          handle, filename = tempfile.mkstemp(suffix=".xml.gz")
    124          f = gzip.open(filename, 'wb')
    125          f.write(self.root_str)
    126          f.close()
    127          try:
    128              f_gz = gzip.open(filename, 'rb')
    129              tree = self.etree.parse(f_gz)
    130              f_gz.close()
    131              self.assertEqual(self.etree.tostring(tree.getroot()), self.root_str)
    132          finally:
    133              os.close(handle)
    134              os.remove(filename)
    135
    136 -    def test_class_parse_filename(self):
    137          # (c)ElementTree class ElementTree has a 'parse' method that returns
    138          # the root of the tree
    139
    140          # parse from filename
    141
    142          handle, filename = tempfile.mkstemp(suffix=".xml")
    143          open(filename, 'wb').write(self.root_str)
    144          try:
    145              tree = self.etree.ElementTree()
    146              root = tree.parse(filename)
    147              self.assertEqual(self.etree.tostring(root), self.root_str)
    148          finally:
    149              os.close(handle)
    150              os.remove(filename)
    151
    152 -    def test_class_parse_filename_remove_previous(self):
    153          handle, filename = tempfile.mkstemp(suffix=".xml")
    154          open(filename, 'wb').write(self.root_str)
    155          try:
    156              tree = self.etree.ElementTree()
    157              root = tree.parse(filename)
    158              # and now do it again; previous content should still be there
    159              root2 = tree.parse(filename)
    160              self.assertEquals('a', root.tag)
    161              self.assertEquals('a', root2.tag)
    162              # now remove all references to root2, and parse again
    163              del root2
    164              root3 = tree.parse(filename)
    165              self.assertEquals('a', root.tag)
    166              self.assertEquals('a', root3.tag)
    167              # root2's memory should've been freed here
    168              # XXX how to check?
    169          finally:
    170              os.close(handle)
    171              os.remove(filename)
    172
    173 -    def test_class_parse_fileobject(self):
    174          # (c)ElementTree class ElementTree has a 'parse' method that returns
    175          # the root of the tree
    176
    177          # parse from file object
    178
    179          handle, filename = tempfile.mkstemp(suffix=".xml")
    180          os.write(handle, self.root_str)
    181          try:
    182              f = open(filename, 'rb')
    183              tree = self.etree.ElementTree()
    184              root = tree.parse(f)
    185              f.close()
    186              self.assertEqual(self.etree.tostring(root), self.root_str)
    187          finally:
    188              os.close(handle)
    189              os.remove(filename)
    190
    191 -    def test_class_parse_unamed_fileobject(self):
    192          # (c)ElementTree class ElementTree has a 'parse' method that returns
    193          # the root of the tree
    194
    195          # parse from unamed file object
    196          f = SillyFileLike()
    197          root = self.etree.ElementTree().parse(f)
    198          self.assert_(root.tag.endswith('foo'))
    199
    200 -    def test_module_parse_large_fileobject(self):
    201          # parse from unamed file object
    202          f = LargeFileLike()
    203          tree = self.etree.parse(f)
    204          root = tree.getroot()
    205          self.assert_(root.tag.endswith('root'))
    206
    207 -    def test_module_parse_fileobject_error(self):
    208          class LocalError(Exception):
    209              pass
    210          class TestFile:
    211              def read(*args):
    212                  raise LocalError
    213          f = TestFile()
    214          self.assertRaises(LocalError, self.etree.parse, f)
    215
    216 -    def test_module_parse_fileobject_late_error(self):
    217          class LocalError(Exception):
    218              pass
    219          class TestFile:
    220              data = '<root>test</'
    221              try:
    222                  next_char = iter(data).next
    223              except AttributeError:
    224                  # Python 3
    225                  next_char = iter(data).__next__
    226              counter = 0
    227              def read(self, amount=None):
    228                  if amount is None:
    229                      while True:
    230                          self.read(1)
    231                  else:
    232                      try:
    233                          self.counter += 1
    234                          return _bytes(self.next_char())
    235                      except StopIteration:
    236                          raise LocalError
    237          f = TestFile()
    238          self.assertRaises(LocalError, self.etree.parse, f)
    239          self.assertEquals(f.counter, len(f.data)+1)
    240
    241 -    def test_module_parse_fileobject_type_error(self):
    242          class TestFile:
    243              def read(*args):
    244                  return 1
    245          f = TestFile()
    246          self.assertRaises(TypeError, self.etree.parse, f)
    247
    248
    249 -class ETreeIOTestCase(IOTestCaseBase):
    250      etree = etree
    251
    252  if ElementTree:
    253 -    class ElementTreeIOTestCase(IOTestCaseBase):
    254          etree = ElementTree
    255
    256 -def test_suite():
    257      suite = unittest.TestSuite()
    258      suite.addTests([unittest.makeSuite(ETreeIOTestCase)])
    259      if ElementTree:
    260          suite.addTests([unittest.makeSuite(ElementTreeIOTestCase)])
    261      return suite
    262
    263  if __name__ == '__main__':
    264      print('to test use test.py %s' % __file__)
    265