Package lxml :: Package tests :: Module test_etree |
[hide private]
[frames] | no frames]

# Source Code for Module lxml.tests.test_etree

       1  # -*- coding: utf-8 -*-
       2
       3  """
       4  Tests specific to the extended etree API
       5
       6  Tests that apply to the general ElementTree API should go into
       7  test_elementtree
       8  """
       9
      10  import os.path
      11  import unittest
      12  import copy
      13  import sys
      14  import re
      15  import operator
      16  import tempfile
      17  import gzip
      18
      19  this_dir = os.path.dirname(__file__)
      20  if this_dir not in sys.path:
      21      sys.path.insert(0, this_dir) # needed for Py3
      22
      23  from common_imports import etree, StringIO, BytesIO, HelperTestCase, fileInTestDir, read_file
      24  from common_imports import SillyFileLike, LargeFileLikeUnicode, doctest, make_doctest
      25  from common_imports import canonicalize, sorted, _str, _bytes
      26
      27  print("")
      28  print("TESTED VERSION: %s" % etree.__version__)
      29  print("    Python:           " + repr(sys.version_info))
      30  print("    lxml.etree:       " + repr(etree.LXML_VERSION))
      31  print("    libxml used:      " + repr(etree.LIBXML_VERSION))
      32  print("    libxml compiled:  " + repr(etree.LIBXML_COMPILED_VERSION))
      33  print("    libxslt used:     " + repr(etree.LIBXSLT_VERSION))
      34  print("    libxslt compiled: " + repr(etree.LIBXSLT_COMPILED_VERSION))
      35  print("")
      36
      37  try:
      38      _unicode = unicode
      39  except NameError:
      40      # Python 3
      41      _unicode = str
      42
      43 -class ETreeOnlyTestCase(HelperTestCase):
      44      """Tests only for etree, not ElementTree"""
      45      etree = etree
      46
      47 -    def test_version(self):
      48          self.assert_(isinstance(etree.__version__, _unicode))
      49          self.assert_(isinstance(etree.LXML_VERSION, tuple))
      50          self.assertEqual(len(etree.LXML_VERSION), 4)
      51          self.assert_(isinstance(etree.LXML_VERSION[0], int))
      52          self.assert_(isinstance(etree.LXML_VERSION[1], int))
      53          self.assert_(isinstance(etree.LXML_VERSION[2], int))
      54          self.assert_(isinstance(etree.LXML_VERSION[3], int))
      55          self.assert_(etree.__version__.startswith(
      56              str(etree.LXML_VERSION[0])))
      57
      58 -    def test_c_api(self):
      59          if hasattr(self.etree, '__pyx_capi__'):
      60              # newer Pyrex compatible C-API
      61              self.assert_(isinstance(self.etree.__pyx_capi__, dict))
      62              self.assert_(len(self.etree.__pyx_capi__) > 0)
      63          else:
      64              # older C-API mechanism
      65              self.assert_(hasattr(self.etree, '_import_c_api'))
      66
      67 -    def test_element_names(self):
      68          Element = self.etree.Element
      69          el = Element('name')
      70          self.assertEquals(el.tag, 'name')
      71          el = Element('{}name')
      72          self.assertEquals(el.tag, 'name')
      73
      74 -    def test_element_name_empty(self):
      75          Element = self.etree.Element
      76          el = Element('name')
      77          self.assertRaises(ValueError, Element, '{}')
      78          self.assertRaises(ValueError, setattr, el, 'tag', '{}')
      79
      80          self.assertRaises(ValueError, Element, '{test}')
      81          self.assertRaises(ValueError, setattr, el, 'tag', '{test}')
      82
      83 -    def test_element_name_colon(self):
      84          Element = self.etree.Element
      85          self.assertRaises(ValueError, Element, 'p:name')
      86          self.assertRaises(ValueError, Element, '{test}p:name')
      87
      88          el = Element('name')
      89          self.assertRaises(ValueError, setattr, el, 'tag', 'p:name')
      90
      91 -    def test_element_name_quote(self):
      92          Element = self.etree.Element
      93          self.assertRaises(ValueError, Element, "p'name")
      94          self.assertRaises(ValueError, Element, 'p"name')
      95
      96          self.assertRaises(ValueError, Element, "{test}p'name")
      97          self.assertRaises(ValueError, Element, '{test}p"name')
      98
      99          el = Element('name')
     100          self.assertRaises(ValueError, setattr, el, 'tag', "p'name")
     101          self.assertRaises(ValueError, setattr, el, 'tag', 'p"name')
     102
     103 -    def test_element_name_space(self):
     104          Element = self.etree.Element
     105          self.assertRaises(ValueError, Element, ' name ')
     106          self.assertRaises(ValueError, Element, 'na me')
     107          self.assertRaises(ValueError, Element, '{test} name')
     108
     109          el = Element('name')
     110          self.assertRaises(ValueError, setattr, el, 'tag', ' name ')
     111
     112 -    def test_subelement_name_empty(self):
     113          Element = self.etree.Element
     114          SubElement = self.etree.SubElement
     115
     116          el = Element('name')
     117          self.assertRaises(ValueError, SubElement, el, '{}')
     118          self.assertRaises(ValueError, SubElement, el, '{test}')
     119
     120 -    def test_subelement_name_colon(self):
     121          Element = self.etree.Element
     122          SubElement = self.etree.SubElement
     123
     124          el = Element('name')
     125          self.assertRaises(ValueError, SubElement, el, 'p:name')
     126          self.assertRaises(ValueError, SubElement, el, '{test}p:name')
     127
     128 -    def test_subelement_name_quote(self):
     129          Element = self.etree.Element
     130          SubElement = self.etree.SubElement
     131
     132          el = Element('name')
     133          self.assertRaises(ValueError, SubElement, el, "p'name")
     134          self.assertRaises(ValueError, SubElement, el, "{test}p'name")
     135
     136          self.assertRaises(ValueError, SubElement, el, 'p"name')
     137          self.assertRaises(ValueError, SubElement, el, '{test}p"name')
     138
     139 -    def test_subelement_name_space(self):
     140          Element = self.etree.Element
     141          SubElement = self.etree.SubElement
     142
     143          el = Element('name')
     144          self.assertRaises(ValueError, SubElement, el, ' name ')
     145          self.assertRaises(ValueError, SubElement, el, 'na me')
     146          self.assertRaises(ValueError, SubElement, el, '{test} name')
     147
     148 -    def test_subelement_attribute_invalid(self):
     149          Element = self.etree.Element
     150          SubElement = self.etree.SubElement
     151
     152          el = Element('name')
     153          self.assertRaises(ValueError, SubElement, el, 'name', {'a b c' : 'abc'})
     154          self.assertRaises(ValueError, SubElement, el, 'name', {'a' : 'a\0\n'})
     155          self.assertEquals(0, len(el))
     156
     157 -    def test_qname_empty(self):
     158          QName = self.etree.QName
     159          self.assertRaises(ValueError, QName, '')
     160          self.assertRaises(ValueError, QName, 'test', '')
     161
     162 -    def test_qname_colon(self):
     163          QName = self.etree.QName
     164          self.assertRaises(ValueError, QName, 'p:name')
     165          self.assertRaises(ValueError, QName, 'test', 'p:name')
     166
     167 -    def test_qname_space(self):
     168          QName = self.etree.QName
     169          self.assertRaises(ValueError, QName, ' name ')
     170          self.assertRaises(ValueError, QName, 'na me')
     171          self.assertRaises(ValueError, QName, 'test', ' name')
     172
     173 -    def test_qname_namespace_localname(self):
     174          # ET doesn't have namespace/localname properties on QNames
     175          QName = self.etree.QName
     176          namespace, localname = 'http://myns', 'a'
     177          qname = QName(namespace, localname)
     178          self.assertEquals(namespace, qname.namespace)
     179          self.assertEquals(localname, qname.localname)
     180
     181 -    def test_qname_element(self):
     182          # ET doesn't have namespace/localname properties on QNames
     183          QName = self.etree.QName
     184          qname1 = QName('http://myns', 'a')
     185          a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'})
     186
     187          qname2 = QName(a)
     188          self.assertEquals(a.tag, qname1.text)
     189          self.assertEquals(qname1.text, qname2.text)
     190          self.assertEquals(qname1, qname2)
     191
     192 -    def test_qname_text_resolve(self):
     193          # ET doesn't resove QNames as text values
     194          etree = self.etree
     195          qname = etree.QName('http://myns', 'a')
     196          a = etree.Element(qname, nsmap={'p' : 'http://myns'})
     197          a.text = qname
     198
     199          self.assertEquals("p:a", a.text)
     200
     201 -    def test_nsmap_prefix_invalid(self):
     202          etree = self.etree
     203          self.assertRaises(ValueError,
     204                            etree.Element, "root", nsmap={'"' : 'testns'})
     205          self.assertRaises(ValueError,
     206                            etree.Element, "root", nsmap={'&' : 'testns'})
     207          self.assertRaises(ValueError,
     208                            etree.Element, "root", nsmap={'a:b' : 'testns'})
     209
     210 -    def test_attribute_has_key(self):
     211          # ET in Py 3.x has no "attrib.has_key()" method
     212          XML = self.etree.XML
     213
     214          root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
     215          self.assertEquals(
     216              True, root.attrib.has_key('bar'))
     217          self.assertEquals(
     218              False, root.attrib.has_key('baz'))
     219          self.assertEquals(
     220              False, root.attrib.has_key('hah'))
     221          self.assertEquals(
     222              True,
     223              root.attrib.has_key('{http://ns.codespeak.net/test}baz'))
     224
     225 -    def test_attribute_set(self):
     226          Element = self.etree.Element
     227          root = Element("root")
     228          root.set("attr", "TEST")
     229          self.assertEquals("TEST", root.get("attr"))
     230
     231 -    def test_attribute_set_invalid(self):
     232          # ElementTree accepts arbitrary attribute values
     233          # lxml.etree allows only strings
     234          Element = self.etree.Element
     235          root = Element("root")
     236          self.assertRaises(TypeError, root.set, "newattr", 5)
     237          self.assertRaises(TypeError, root.set, "newattr", None)
     238
     239 -    def test_strip_attributes(self):
     240          XML = self.etree.XML
     241          xml = _bytes('<test a="5" b="10" c="20"><x a="4" b="2"/></test>')
     242
     243          root = XML(xml)
     244          self.etree.strip_attributes(root, 'a')
     245          self.assertEquals(_bytes('<test b="10" c="20"><x b="2"></x></test>'),
     246                            self._writeElement(root))
     247
     248          root = XML(xml)
     249          self.etree.strip_attributes(root, 'b', 'c')
     250          self.assertEquals(_bytes('<test a="5"><x a="4"></x></test>'),
     251                            self._writeElement(root))
     252
     253 -    def test_strip_attributes_ns(self):
     254          XML = self.etree.XML
     255          xml = _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20" n:a="5"><x a="4" n:b="2"/></test>')
     256
     257          root = XML(xml)
     258          self.etree.strip_attributes(root, 'a')
     259          self.assertEquals(
     260              _bytes('<test xmlns:n="http://test/ns" b="10" c="20" n:a="5"><x n:b="2"></x></test>'),
     261              self._writeElement(root))
     262
     263          root = XML(xml)
     264          self.etree.strip_attributes(root, '{http://test/ns}a', 'c')
     265          self.assertEquals(
     266              _bytes('<test xmlns:n="http://test/ns" a="6" b="10"><x a="4" n:b="2"></x></test>'),
     267              self._writeElement(root))
     268
     269          root = XML(xml)
     270          self.etree.strip_attributes(root, '{http://test/ns}*')
     271          self.assertEquals(
     272              _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20"><x a="4"></x></test>'),
     273              self._writeElement(root))
     274
     275 -    def test_strip_elements(self):
     276          XML = self.etree.XML
     277          xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>')
     278
     279          root = XML(xml)
     280          self.etree.strip_elements(root, 'a')
     281          self.assertEquals(_bytes('<test><x></x></test>'),
     282                            self._writeElement(root))
     283
     284          root = XML(xml)
     285          self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z')
     286          self.assertEquals(_bytes('<test><a></a><x><a></a></x></test>'),
     287                            self._writeElement(root))
     288
     289          root = XML(xml)
     290          self.etree.strip_elements(root, 'c')
     291          self.assertEquals(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'),
     292                            self._writeElement(root))
     293
     294 -    def test_strip_elements_ns(self):
     295          XML = self.etree.XML
     296          xml = _bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"/>C</b>BT</n:a>AT<x>X<a>A<b xmlns="urn:a"/>BT<c xmlns="urn:x"/>CT</a>AT</x>XT</test>')
     297
     298          root = XML(xml)
     299          self.etree.strip_elements(root, 'a')
     300          self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>C</b>BT</n:a>AT<x>X</x>XT</test>'),
     301                            self._writeElement(root))
     302
     303          root = XML(xml)
     304          self.etree.strip_elements(root, '{urn:a}b', 'c')
     305          self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>C</b>BT</n:a>AT<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
     306                            self._writeElement(root))
     307
     308          root = XML(xml)
     309          self.etree.strip_elements(root, '{urn:a}*', 'c')
     310          self.assertEquals(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
     311                            self._writeElement(root))
     312
     313          root = XML(xml)
     314          self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False)
     315          self.assertEquals(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
     316                            self._writeElement(root))
     317
     318 -    def test_strip_tags(self):
     319          XML = self.etree.XML
     320          xml = _bytes('<test>TEST<a>A<b>B<c/>CT</b>BT</a>AT<x>X<a>A<b/>BT<c/>CT</a>AT</x>XT</test>')
     321
     322          root = XML(xml)
     323          self.etree.strip_tags(root, 'a')
     324          self.assertEquals(_bytes('<test>TESTA<b>B<c></c>CT</b>BTAT<x>XA<b></b>BT<c></c>CTAT</x>XT</test>'),
     325                            self._writeElement(root))
     326
     327          root = XML(xml)
     328          self.etree.strip_tags(root, 'b', 'c', 'X', 'Y', 'Z')
     329          self.assertEquals(_bytes('<test>TEST<a>ABCTBT</a>AT<x>X<a>ABTCT</a>AT</x>XT</test>'),
     330                            self._writeElement(root))
     331
     332          root = XML(xml)
     333          self.etree.strip_tags(root, 'c')
     334          self.assertEquals(_bytes('<test>TEST<a>A<b>BCT</b>BT</a>AT<x>X<a>A<b></b>BTCT</a>AT</x>XT</test>'),
     335                            self._writeElement(root))
     336
     337 -    def test_strip_tags_pi_comment(self):
     338          XML = self.etree.XML
     339          PI = self.etree.ProcessingInstruction
     340          Comment = self.etree.Comment
     341          xml = _bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT<?PI2?></test>\n<!--comment3-->\n<?PI1?>')
     342
     343          root = XML(xml)
     344          self.etree.strip_tags(root, PI)
     345          self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT</test>\n<!--comment3-->\n<?PI1?>'),
     346                            self._writeElement(root))
     347
     348          root = XML(xml)
     349          self.etree.strip_tags(root, Comment)
     350          self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT<?PI2?></test>\n<!--comment3-->\n<?PI1?>'),
     351                            self._writeElement(root))
     352
     353          root = XML(xml)
     354          self.etree.strip_tags(root, PI, Comment)
     355          self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT</test>\n<!--comment3-->\n<?PI1?>'),
     356                            self._writeElement(root))
     357
     358          root = XML(xml)
     359          self.etree.strip_tags(root, Comment, PI)
     360          self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT</test>\n<!--comment3-->\n<?PI1?>'),
     361                            self._writeElement(root))
     362
     363 -    def test_strip_tags_pi_comment_all(self):
     364          XML = self.etree.XML
     365          ElementTree = self.etree.ElementTree
     366          PI = self.etree.ProcessingInstruction
     367          Comment = self.etree.Comment
     368          xml = _bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT<?PI2?></test>\n<!--comment3-->\n<?PI1?>')
     369
     370          root = XML(xml)
     371          self.etree.strip_tags(ElementTree(root), PI)
     372          self.assertEquals(_bytes('<!--comment1-->\n<test>TEST<!--comment2-->XT</test>\n<!--comment3-->'),
     373                            self._writeElement(root))
     374
     375          root = XML(xml)
     376          self.etree.strip_tags(ElementTree(root), Comment)
     377          self.assertEquals(_bytes('<?PI1?>\n<test>TESTXT<?PI2?></test>\n<?PI1?>'),
     378                            self._writeElement(root))
     379
     380          root = XML(xml)
     381          self.etree.strip_tags(ElementTree(root), PI, Comment)
     382          self.assertEquals(_bytes('<test>TESTXT</test>'),
     383                            self._writeElement(root))
     384
     385          root = XML(xml)
     386          self.etree.strip_tags(ElementTree(root), Comment, PI)
     387          self.assertEquals(_bytes('<test>TESTXT</test>'),
     388                            self._writeElement(root))
     389
     390 -    def test_strip_tags_doc_style(self):
     391          XML = self.etree.XML
     392          xml = _bytes('''
     393          <div>
     394              <div>
     395                  I like <strong>sheep</strong>.
     396                  <br/>
     397                  I like lots of <strong>sheep</strong>.
     398                  <br/>
     399                  Click <a href="http://www.sheep.com">here</a> for <a href="http://www.sheep.com">those</a> sheep.
     400                  <br/>
     401              </div>
     402          </div>
     403          '''.strip())
     404
     405          root = XML(xml)
     406          self.etree.strip_tags(root, 'a')
     407          self.assertEquals(re.sub(_bytes('</?a[^>]*>'), _bytes(''), xml).replace(_bytes('<br/>'), _bytes('<br></br>')),
     408                            self._writeElement(root))
     409
     410          root = XML(xml)
     411          self.etree.strip_tags(root, 'a', 'br')
     412          self.assertEquals(re.sub(_bytes('</?a[^>]*>'), _bytes(''),
     413                                   re.sub(_bytes('<br[^>]*>'), _bytes(''), xml)),
     414                            self._writeElement(root))
     415
     416 -    def test_strip_tags_ns(self):
     417          XML = self.etree.XML
     418          xml = _bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"/>CT</b>BT</n:a>AT<x>X<a>A<b xmlns="urn:a"/>BT<c xmlns="urn:x"/>CT</a>AT</x>XT</test>')
     419
     420          root = XML(xml)
     421          self.etree.strip_tags(root, 'a')
     422          self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>CT</b>BT</n:a>AT<x>XA<b xmlns="urn:a"></b>BT<c xmlns="urn:x"></c>CTAT</x>XT</test>'),
     423                            self._writeElement(root))
     424
     425          root = XML(xml)
     426          self.etree.strip_tags(root, '{urn:a}b', 'c')
     427          self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>CT</b>BT</n:a>AT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
     428                            self._writeElement(root))
     429
     430          root = XML(xml)
     431          self.etree.strip_tags(root, '{urn:a}*', 'c')
     432          self.assertEquals(_bytes('<test>TESTA<b>B<c xmlns="urn:c"></c>CT</b>BTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
     433                            self._writeElement(root))
     434
     435 -    def test_strip_tags_and_remove(self):
     436          # previously crashed
     437          HTML = self.etree.HTML
     438          root = HTML(_bytes('<div><h1>title</h1> <b>foo</b> <p>boo</p></div>'))[0][0]
     439          self.assertEquals(_bytes('<div><h1>title</h1> <b>foo</b> <p>boo</p></div>'),
     440                            self.etree.tostring(root))
     441          self.etree.strip_tags(root, 'b')
     442          self.assertEquals(_bytes('<div><h1>title</h1> foo <p>boo</p></div>'),
     443                            self.etree.tostring(root))
     444          root.remove(root[0])
     445          self.assertEquals(_bytes('<div><p>boo</p></div>'),
     446                            self.etree.tostring(root))
     447
     448 -    def test_pi(self):
     449          # lxml.etree separates target and text
     450          Element = self.etree.Element
     451          SubElement = self.etree.SubElement
     452          ProcessingInstruction = self.etree.ProcessingInstruction
     453
     454          a = Element('a')
     455          a.append(ProcessingInstruction('foo', 'some more text'))
     456          self.assertEquals(a[0].target, 'foo')
     457          self.assertEquals(a[0].text, 'some more text')
     458
     459 -    def test_pi_parse(self):
     460          XML = self.etree.XML
     461          root = XML(_bytes("<test><?mypi my test ?></test>"))
     462          self.assertEquals(root[0].target, "mypi")
     463          self.assertEquals(root[0].text, "my test ")
     464
     465 -    def test_pi_pseudo_attributes_get(self):
     466          XML = self.etree.XML
     467          root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
     468          self.assertEquals(root[0].target, "mypi")
     469          self.assertEquals(root[0].get('my'), "1")
     470          self.assertEquals(root[0].get('test'), " abc ")
     471          self.assertEquals(root[0].get('quotes'), "' '")
     472          self.assertEquals(root[0].get('only'), None)
     473          self.assertEquals(root[0].get('names'), None)
     474          self.assertEquals(root[0].get('nope'), None)
     475
     476 -    def test_pi_pseudo_attributes_attrib(self):
     477          XML = self.etree.XML
     478          root = XML(_bytes("<test><?mypi my='1' test=\" abc \" quotes=\"' '\" only names ?></test>"))
     479          self.assertEquals(root[0].target, "mypi")
     480          self.assertEquals(root[0].attrib['my'], "1")
     481          self.assertEquals(root[0].attrib['test'], " abc ")
     482          self.assertEquals(root[0].attrib['quotes'], "' '")
     483          self.assertRaises(KeyError, root[0].attrib.__getitem__, 'only')
     484          self.assertRaises(KeyError, root[0].attrib.__getitem__, 'names')
     485          self.assertRaises(KeyError, root[0].attrib.__getitem__, 'nope')
     486
     487 -    def test_deepcopy_pi(self):
     488          # previously caused a crash
     489          ProcessingInstruction = self.etree.ProcessingInstruction
     490
     491          a = ProcessingInstruction("PI", "ONE")
     492          b = copy.deepcopy(a)
     493          b.text = "ANOTHER"
     494
     495          self.assertEquals('ONE',     a.text)
     496          self.assertEquals('ANOTHER', b.text)
     497
     498 -    def test_deepcopy_elementtree_pi(self):
     499          XML = self.etree.XML
     500          tostring = self.etree.tostring
     501          root = XML(_bytes("<?mypi my test ?><test/><!--comment -->"))
     502          tree1 = self.etree.ElementTree(root)
     503          self.assertEquals(_bytes("<?mypi my test ?><test/><!--comment -->"),
     504                            tostring(tree1))
     505
     506          tree2 = copy.deepcopy(tree1)
     507          self.assertEquals(_bytes("<?mypi my test ?><test/><!--comment -->"),
     508                            tostring(tree2))
     509
     510          root2 = copy.deepcopy(tree1.getroot())
     511          self.assertEquals(_bytes("<test/>"),
     512                            tostring(root2))
     513
     514 -    def test_deepcopy_elementtree_dtd(self):
     515          XML = self.etree.XML
     516          tostring = self.etree.tostring
     517          xml = _bytes('<!DOCTYPE test [\n<!ENTITY entity "tasty">\n]>\n<test/>')
     518          root = XML(xml)
     519          tree1 = self.etree.ElementTree(root)
     520          self.assertEquals(xml, tostring(tree1))
     521
     522          tree2 = copy.deepcopy(tree1)
     523          self.assertEquals(xml, tostring(tree2))
     524
     525          root2 = copy.deepcopy(tree1.getroot())
     526          self.assertEquals(_bytes("<test/>"),
     527                            tostring(root2))
     528
     529 -    def test_attribute_set(self):
     530          # ElementTree accepts arbitrary attribute values
     531          # lxml.etree allows only strings
     532          Element = self.etree.Element
     533
     534          root = Element("root")
     535          root.set("attr", "TEST")
     536          self.assertEquals("TEST", root.get("attr"))
     537          self.assertRaises(TypeError, root.set, "newattr", 5)
     538
     539 -    def test_parse_remove_comments(self):
     540          fromstring = self.etree.fromstring
     541          tostring = self.etree.tostring
     542          XMLParser = self.etree.XMLParser
     543
     544          xml = _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
     545          parser = XMLParser(remove_comments=True)
     546          root = fromstring(xml, parser)
     547          self.assertEquals(
     548              _bytes('<a><b><c/></b></a>'),
     549              tostring(root))
     550
     551 -    def test_parse_remove_pis(self):
     552          parse = self.etree.parse
     553          tostring = self.etree.tostring
     554          XMLParser = self.etree.XMLParser
     555
     556          xml = _bytes('<?test?><a><?A?><b><?B?><c/></b><?C?></a><?tail?>')
     557
     558          f = BytesIO(xml)
     559          tree = parse(f)
     560          self.assertEquals(
     561              xml,
     562              tostring(tree))
     563
     564          parser = XMLParser(remove_pis=True)
     565          tree = parse(f, parser)
     566          self.assertEquals(
     567              _bytes('<a><b><c/></b></a>'),
     568              tostring(tree))
     569
     570 -    def test_parse_parser_type_error(self):
     571          # ET raises IOError only
     572          parse = self.etree.parse
     573          self.assertRaises(TypeError, parse, 'notthere.xml', object())
     574
     575 -    def test_iterparse_tree_comments(self):
     576          # ET removes comments
     577          iterparse = self.etree.iterparse
     578          tostring = self.etree.tostring
     579
     580          f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
     581          events = list(iterparse(f))
     582          root = events[-1][1]
     583          self.assertEquals(3, len(events))
     584          self.assertEquals(
     585              _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'),
     586              tostring(root))
     587
     588 -    def test_iterparse_comments(self):
     589          # ET removes comments
     590          iterparse = self.etree.iterparse
     591          tostring = self.etree.tostring
     592
     593          def name(event, el):
     594              if event == 'comment':
     595                  return el.text
     596              else:
     597                  return el.tag
     598
     599          f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
     600          events = list(iterparse(f, events=('end', 'comment')))
     601          root = events[-1][1]
     602          self.assertEquals(6, len(events))
     603          self.assertEquals(['A', ' B ', 'c', 'b', 'C', 'a'],
     604                            [ name(*item) for item in events ])
     605          self.assertEquals(
     606              _bytes('<a><!--A--><b><!-- B --><c/></b><!--C--></a>'),
     607              tostring(root))
     608
     609 -    def test_iterparse_pis(self):
     610          # ET removes pis
     611          iterparse = self.etree.iterparse
     612          tostring = self.etree.tostring
     613          ElementTree = self.etree.ElementTree
     614
     615          def name(event, el):
     616              if event == 'pi':
     617                  return (el.target, el.text)
     618              else:
     619                  return el.tag
     620
     621          f = BytesIO('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>')
     622          events = list(iterparse(f, events=('end', 'pi')))
     623          root = events[-2][1]
     624          self.assertEquals(8, len(events))
     625          self.assertEquals([('pia','a'), ('pib','b'), ('pic','c'), 'c', 'b',
     626                             ('pid','d'), 'a', ('pie','e')],
     627                            [ name(*item) for item in events ])
     628          self.assertEquals(
     629              _bytes('<?pia a?><a><?pib b?><b><?pic c?><c/></b><?pid d?></a><?pie e?>'),
     630              tostring(ElementTree(root)))
     631
     632 -    def test_iterparse_remove_comments(self):
     633          iterparse = self.etree.iterparse
     634          tostring = self.etree.tostring
     635
     636          f = BytesIO('<a><!--A--><b><!-- B --><c/></b><!--C--></a>')
     637          events = list(iterparse(f, remove_comments=True,
     638                                  events=('end', 'comment')))
     639          root = events[-1][1]
     640          self.assertEquals(3, len(events))
     641          self.assertEquals(['c', 'b', 'a'],
     642                            [ el.tag for (event, el) in events ])
     643          self.assertEquals(
     644              _bytes('<a><b><c/></b></a>'),
     645              tostring(root))
     646
     647 -    def test_iterparse_broken(self):
     648          iterparse = self.etree.iterparse
     649          f = BytesIO('<a><b><c/></a>')
     650          # ET raises ExpatError, lxml raises XMLSyntaxError
     651          self.assertRaises(self.etree.XMLSyntaxError, list, iterparse(f))
     652
     653 -    def test_iterparse_strip(self):
     654          iterparse = self.etree.iterparse
     655          f = BytesIO("""
     656                 <a>  \n \n  <b> b test </b>  \n
     657
     658                 \n\t <c> \n </c> </a>  \n """)
     659          iterator = iterparse(f, remove_blank_text=True)
     660          text = [ (element.text, element.tail)
     661                   for event, element in iterator ]
     662          self.assertEquals(
     663              [(" b test ", None), (" \n ", None), (None, None)],
     664              text)
     665
     666 -    def test_iterparse_tag(self):
     667          iterparse = self.etree.iterparse
     668          f = BytesIO('<a><b><d/></b><c/></a>')
     669
     670          iterator = iterparse(f, tag="b", events=('start', 'end'))
     671          events = list(iterator)
     672          root = iterator.root
     673          self.assertEquals(
     674              [('start', root[0]), ('end', root[0])],
     675              events)
     676
     677 -    def test_iterparse_tag_all(self):
     678          iterparse = self.etree.iterparse
     679          f = BytesIO('<a><b><d/></b><c/></a>')
     680
     681          iterator = iterparse(f, tag="*", events=('start', 'end'))
     682          events = list(iterator)
     683          self.assertEquals(
     684              8,
     685              len(events))
     686
     687 -    def test_iterparse_tag_ns(self):
     688          iterparse = self.etree.iterparse
     689          f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
     690
     691          iterator = iterparse(f, tag="{urn:test:1}b", events=('start', 'end'))
     692          events = list(iterator)
     693          root = iterator.root
     694          self.assertEquals(
     695              [('start', root[0]), ('end', root[0])],
     696              events)
     697
     698 -    def test_iterparse_tag_ns_empty(self):
     699          iterparse = self.etree.iterparse
     700          f = BytesIO('<a><b><d/></b><c/></a>')
     701          iterator = iterparse(f, tag="{}b", events=('start', 'end'))
     702          events = list(iterator)
     703          root = iterator.root
     704          self.assertEquals(
     705              [('start', root[0]), ('end', root[0])],
     706              events)
     707
     708          f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
     709          iterator = iterparse(f, tag="{}b", events=('start', 'end'))
     710          events = list(iterator)
     711          root = iterator.root
     712          self.assertEquals([], events)
     713
     714 -    def test_iterparse_tag_ns_all(self):
     715          iterparse = self.etree.iterparse
     716          f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
     717          iterator = iterparse(f, tag="{urn:test:1}*", events=('start', 'end'))
     718          events = list(iterator)
     719          self.assertEquals(8, len(events))
     720
     721 -    def test_iterparse_tag_ns_empty_all(self):
     722          iterparse = self.etree.iterparse
     723          f = BytesIO('<a xmlns="urn:test:1"><b><d/></b><c/></a>')
     724          iterator = iterparse(f, tag="{}*", events=('start', 'end'))
     725          events = list(iterator)
     726          self.assertEquals([], events)
     727
     728          f = BytesIO('<a><b><d/></b><c/></a>')
     729          iterator = iterparse(f, tag="{}*", events=('start', 'end'))
     730          events = list(iterator)
     731          self.assertEquals(8, len(events))
     732
     733 -    def test_iterparse_encoding_error(self):
     734          text = _str('Søk på nettet')
     735          wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
     736          xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
     737                        ).encode('iso-8859-1')
     738
     739          self.assertRaises(self.etree.ParseError,
     740                            list, self.etree.iterparse(BytesIO(xml_latin1)))
     741
     742 -    def test_iterparse_encoding_8bit_override(self):
     743          text = _str('Søk på nettet', encoding="UTF-8")
     744          wrong_declaration = "<?xml version='1.0' encoding='UTF-8'?>"
     745          xml_latin1 = (_str('%s<a>%s</a>') % (wrong_declaration, text)
     746                        ).encode('iso-8859-1')
     747
     748          iterator = self.etree.iterparse(BytesIO(xml_latin1),
     749                                          encoding="iso-8859-1")
     750          self.assertEquals(1, len(list(iterator)))
     751
     752          a = iterator.root
     753          self.assertEquals(a.text, text)
     754
     755 -    def test_iterparse_keep_cdata(self):
     756          tostring = self.etree.tostring
     757          f = BytesIO('<root><![CDATA[test]]></root>')
     758          context = self.etree.iterparse(f, strip_cdata=False)
     759          content = [ el.text for event,el in context ]
     760
     761          self.assertEquals(['test'], content)
     762          self.assertEquals(_bytes('<root><![CDATA[test]]></root>'),
     763                            tostring(context.root))
     764
     765 -    def test_parser_encoding_unknown(self):
     766          self.assertRaises(
     767              LookupError, self.etree.XMLParser, encoding="hopefully unknown")
     768
     769 -    def test_parser_encoding(self):
     770          self.etree.XMLParser(encoding="ascii")
     771          self.etree.XMLParser(encoding="utf-8")
     772          self.etree.XMLParser(encoding="iso-8859-1")
     773
     774 -    def test_feed_parser_recover(self):
     775          parser = self.etree.XMLParser(recover=True)
     776
     777          parser.feed('<?xml version=')
     778          parser.feed('"1.0"?><ro')
     779          parser.feed('ot><')
     780          parser.feed('a test="works"')
     781          parser.feed('><othertag/></root') # <a> not closed!
     782          parser.feed('>')
     783
     784          root = parser.close()
     785
     786          self.assertEquals(root.tag, "root")
     787          self.assertEquals(len(root), 1)
     788          self.assertEquals(root[0].tag, "a")
     789          self.assertEquals(root[0].get("test"), "works")
     790          self.assertEquals(len(root[0]), 1)
     791          self.assertEquals(root[0][0].tag, "othertag")
     792          # FIXME: would be nice to get some errors logged ...
     793          #self.assert_(len(parser.error_log) > 0, "error log is empty")
     794
     795 -    def test_elementtree_parser_target_type_error(self):
     796          assertEquals = self.assertEquals
     797          assertFalse  = self.assertFalse
     798
     799          events = []
     800          class Target(object):
     801              def start(self, tag, attrib):
     802                  events.append("start")
     803                  assertFalse(attrib)
     804                  assertEquals("TAG", tag)
     805              def end(self, tag):
     806                  events.append("end")
     807                  assertEquals("TAG", tag)
     808              def close(self):
     809                  return "DONE" # no Element!
     810
     811          parser = self.etree.XMLParser(target=Target())
     812          tree = self.etree.ElementTree()
     813
     814          self.assertRaises(TypeError,
     815                            tree.parse, BytesIO("<TAG/>"), parser=parser)
     816          self.assertEquals(["start", "end"], events)
     817
     818 -    def test_parser_target_feed_exception(self):
     819          # ET doesn't call .close() on errors
     820          events = []
     821          class Target(object):
     822              def start(self, tag, attrib):
     823                  events.append("start-" + tag)
     824              def end(self, tag):
     825                  events.append("end-" + tag)
     826                  if tag == 'a':
     827                      raise ValueError("dead and gone")
     828              def data(self, data):
     829                  events.append("data-" + data)
     830              def close(self):
     831                  events.append("close")
     832                  return "DONE"
     833
     834          parser = self.etree.XMLParser(target=Target())
     835
     836          try:
     837              parser.feed(_bytes('<root>A<a>ca</a>B</root>'))
     838              done = parser.close()
     839              self.fail("error expected, but parsing succeeded")
     840          except ValueError:
     841              done = 'value error received as expected'
     842
     843          self.assertEquals(["start-root", "data-A", "start-a",
     844                             "data-ca", "end-a", "close"],
     845                            events)
     846
     847 -    def test_parser_target_fromstring_exception(self):
     848          # ET doesn't call .close() on errors
     849          events = []
     850          class Target(object):
     851              def start(self, tag, attrib):
     852                  events.append("start-" + tag)
     853              def end(self, tag):
     854                  events.append("end-" + tag)
     855                  if tag == 'a':
     856                      raise ValueError("dead and gone")
     857              def data(self, data):
     858                  events.append("data-" + data)
     859              def close(self):
     860                  events.append("close")
     861                  return "DONE"
     862
     863          parser = self.etree.XMLParser(target=Target())
     864
     865          try:
     866              done = self.etree.fromstring(_bytes('<root>A<a>ca</a>B</root>'),
     867                                           parser=parser)
     868              self.fail("error expected, but parsing succeeded")
     869          except ValueError:
     870              done = 'value error received as expected'
     871
     872          self.assertEquals(["start-root", "data-A", "start-a",
     873                             "data-ca", "end-a", "close"],
     874                            events)
     875
     876 -    def test_parser_target_comment(self):
     877          events = []
     878          class Target(object):
     879              def start(self, tag, attrib):
     880                  events.append("start-" + tag)
     881              def end(self, tag):
     882                  events.append("end-" + tag)
     883              def data(self, data):
     884                  events.append("data-" + data)
     885              def comment(self, text):
     886                  events.append("comment-" + text)
     887              def close(self):
     888                  return "DONE"
     889
     890          parser = self.etree.XMLParser(target=Target())
     891
     892          parser.feed(_bytes('<!--a--><root>A<!--b--><sub/><!--c-->B</root><!--d-->'))
     893          done = parser.close()
     894
     895          self.assertEquals("DONE", done)
     896          self.assertEquals(["comment-a", "start-root", "data-A", "comment-b",
     897                             "start-sub", "end-sub", "comment-c", "data-B",
     898                             "end-root", "comment-d"],
     899                            events)
     900
     901 -    def test_parser_target_pi(self):
     902          events = []
     903          class Target(object):
     904              def start(self, tag, attrib):
     905                  events.append("start-" + tag)
     906              def end(self, tag):
     907                  events.append("end-" + tag)
     908              def data(self, data):
     909                  events.append("data-" + data)
     910              def pi(self, target, data):
     911                  events.append("pi-" + target + "-" + data)
     912              def close(self):
     913                  return "DONE"
     914
     915          parser = self.etree.XMLParser(target=Target())
     916
     917          parser.feed(_bytes('<?test a?><root>A<?test b?>B</root><?test c?>'))
     918          done = parser.close()
     919
     920          self.assertEquals("DONE", done)
     921          self.assertEquals(["pi-test-a", "start-root", "data-A", "pi-test-b",
     922                             "data-B", "end-root", "pi-test-c"],
     923                            events)
     924
     925 -    def test_parser_target_cdata(self):
     926          events = []
     927          class Target(object):
     928              def start(self, tag, attrib):
     929                  events.append("start-" + tag)
     930              def end(self, tag):
     931                  events.append("end-" + tag)
     932              def data(self, data):
     933                  events.append("data-" + data)
     934              def close(self):
     935                  return "DONE"
     936
     937          parser = self.etree.XMLParser(target=Target(),
     938                                        strip_cdata=False)
     939
     940          parser.feed(_bytes('<root>A<a><![CDATA[ca]]></a>B</root>'))
     941          done = parser.close()
     942
     943          self.assertEquals("DONE", done)
     944          self.assertEquals(["start-root", "data-A", "start-a",
     945                             "data-ca", "end-a", "data-B", "end-root"],
     946                            events)
     947
     948 -    def test_parser_target_recover(self):
     949          events = []
     950          class Target(object):
     951              def start(self, tag, attrib):
     952                  events.append("start-" + tag)
     953              def end(self, tag):
     954                  events.append("end-" + tag)
     955              def data(self, data):
     956                  events.append("data-" + data)
     957              def close(self):
     958                  events.append("close")
     959                  return "DONE"
     960
     961          parser = self.etree.XMLParser(target=Target(),
     962                                        recover=True)
     963
     964          parser.feed(_bytes('<root>A<a>ca</a>B</not-root>'))
     965          done = parser.close()
     966
     967          self.assertEquals("DONE", done)
     968          self.assertEquals(["start-root", "data-A", "start-a",
     969                             "data-ca", "end-a", "data-B",
     970                             "end-root", "close"],
     971                            events)
     972
     973 -    def test_iterwalk_tag(self):
     974          iterwalk = self.etree.iterwalk
     975          root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
     976
     977          iterator = iterwalk(root, tag="b", events=('start', 'end'))
     978          events = list(iterator)
     979          self.assertEquals(
     980              [('start', root[0]), ('end', root[0])],
     981              events)
     982
     983 -    def test_iterwalk_tag_all(self):
     984          iterwalk = self.etree.iterwalk
     985          root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
     986
     987          iterator = iterwalk(root, tag="*", events=('start', 'end'))
     988          events = list(iterator)
     989          self.assertEquals(
     990              8,
     991              len(events))
     992
     993 -    def test_iterwalk(self):
     994          iterwalk = self.etree.iterwalk
     995          root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
     996
     997          events = list(iterwalk(root))
     998          self.assertEquals(
     999              [('end', root[0]), ('end', root[1]), ('end', root)],
    1000              events)
    1001
    1002 -    def test_iterwalk_start(self):
    1003          iterwalk = self.etree.iterwalk
    1004          root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
    1005
    1006          iterator = iterwalk(root, events=('start',))
    1007          events = list(iterator)
    1008          self.assertEquals(
    1009              [('start', root), ('start', root[0]), ('start', root[1])],
    1010              events)
    1011
    1012 -    def test_iterwalk_start_end(self):
    1013          iterwalk = self.etree.iterwalk
    1014          root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
    1015
    1016          iterator = iterwalk(root, events=('start','end'))
    1017          events = list(iterator)
    1018          self.assertEquals(
    1019              [('start', root), ('start', root[0]), ('end', root[0]),
    1020               ('start', root[1]), ('end', root[1]), ('end', root)],
    1021              events)
    1022
    1023 -    def test_iterwalk_clear(self):
    1024          iterwalk = self.etree.iterwalk
    1025          root = self.etree.XML(_bytes('<a><b></b><c/></a>'))
    1026
    1027          iterator = iterwalk(root)
    1028          for event, elem in iterator:
    1029              elem.clear()
    1030
    1031          self.assertEquals(0,
    1032                            len(root))
    1033
    1034 -    def test_iterwalk_attrib_ns(self):
    1035          iterwalk = self.etree.iterwalk
    1036          root = self.etree.XML(_bytes('<a xmlns="ns1"><b><c xmlns="ns2"/></b></a>'))
    1037
    1038          attr_name = '{testns}bla'
    1039          events = []
    1040          iterator = iterwalk(root, events=('start','end','start-ns','end-ns'))
    1041          for event, elem in iterator:
    1042              events.append(event)
    1043              if event == 'start':
    1044                  if elem.tag != '{ns1}a':
    1045                      elem.set(attr_name, 'value')
    1046
    1047          self.assertEquals(
    1048              ['start-ns', 'start', 'start', 'start-ns', 'start',
    1049               'end', 'end-ns', 'end', 'end', 'end-ns'],
    1050              events)
    1051
    1052          self.assertEquals(
    1053              None,
    1054              root.get(attr_name))
    1055          self.assertEquals(
    1056              'value',
    1057              root[0].get(attr_name))
    1058
    1059 -    def test_iterwalk_getiterator(self):
    1060          iterwalk = self.etree.iterwalk
    1061          root = self.etree.XML(_bytes('<a><b><d/></b><c/></a>'))
    1062
    1063          counts = []
    1064          for event, elem in iterwalk(root):
    1065              counts.append(len(list(elem.getiterator())))
    1066          self.assertEquals(
    1067              [1,2,1,4],
    1068              counts)
    1069
    1070 -    def test_resolve_string_dtd(self):
    1071          parse = self.etree.parse
    1072          parser = self.etree.XMLParser(dtd_validation=True)
    1073          assertEqual = self.assertEqual
    1074          test_url = _str("__nosuch.dtd")
    1075
    1076          class MyResolver(self.etree.Resolver):
    1077              def resolve(self, url, id, context):
    1078                  assertEqual(url, test_url)
    1079                  return self.resolve_string(
    1080                      _str('''<!ENTITY myentity "%s">
    1081                          <!ELEMENT doc ANY>''') % url, context)
    1082
    1083          parser.resolvers.add(MyResolver())
    1084
    1085          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
    1086          tree = parse(StringIO(xml), parser)
    1087          root = tree.getroot()
    1088          self.assertEquals(root.text, test_url)
    1089
    1090 -    def test_resolve_bytes_dtd(self):
    1091          parse = self.etree.parse
    1092          parser = self.etree.XMLParser(dtd_validation=True)
    1093          assertEqual = self.assertEqual
    1094          test_url = _str("__nosuch.dtd")
    1095
    1096          class MyResolver(self.etree.Resolver):
    1097              def resolve(self, url, id, context):
    1098                  assertEqual(url, test_url)
    1099                  return self.resolve_string(
    1100                      (_str('''<!ENTITY myentity "%s">
    1101                               <!ELEMENT doc ANY>''') % url).encode('utf-8'),
    1102                      context)
    1103
    1104          parser.resolvers.add(MyResolver())
    1105
    1106          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
    1107          tree = parse(StringIO(xml), parser)
    1108          root = tree.getroot()
    1109          self.assertEquals(root.text, test_url)
    1110
    1111 -    def test_resolve_filelike_dtd(self):
    1112          parse = self.etree.parse
    1113          parser = self.etree.XMLParser(dtd_validation=True)
    1114          assertEqual = self.assertEqual
    1115          test_url = _str("__nosuch.dtd")
    1116
    1117          class MyResolver(self.etree.Resolver):
    1118              def resolve(self, url, id, context):
    1119                  assertEqual(url, test_url)
    1120                  return self.resolve_file(
    1121                      SillyFileLike(
    1122                          _str('''<!ENTITY myentity "%s">
    1123                          <!ELEMENT doc ANY>''') % url), context)
    1124
    1125          parser.resolvers.add(MyResolver())
    1126
    1127          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
    1128          tree = parse(StringIO(xml), parser)
    1129          root = tree.getroot()
    1130          self.assertEquals(root.text, test_url)
    1131
    1132 -    def test_resolve_filename_dtd(self):
    1133          parse = self.etree.parse
    1134          parser = self.etree.XMLParser(attribute_defaults=True)
    1135          assertEqual = self.assertEqual
    1136          test_url = _str("__nosuch.dtd")
    1137
    1138          class MyResolver(self.etree.Resolver):
    1139              def resolve(self, url, id, context):
    1140                  assertEqual(url, test_url)
    1141                  return self.resolve_filename(
    1142                      fileInTestDir('test.dtd'), context)
    1143
    1144          parser.resolvers.add(MyResolver())
    1145
    1146          xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
    1147          tree = parse(StringIO(xml), parser)
    1148          root = tree.getroot()
    1149          self.assertEquals(
    1150              root.attrib,    {'default': 'valueA'})
    1151          self.assertEquals(
    1152              root[0].attrib, {'default': 'valueB'})
    1153
    1154 -    def test_resolve_filename_dtd_relative(self):
    1155          parse = self.etree.parse
    1156          parser = self.etree.XMLParser(attribute_defaults=True)
    1157          assertEqual = self.assertEqual
    1158          test_url = _str("__nosuch.dtd")
    1159
    1160          class MyResolver(self.etree.Resolver):
    1161              def resolve(self, url, id, context):
    1162                  assertEqual(url, fileInTestDir(test_url))
    1163                  return self.resolve_filename(
    1164                      fileInTestDir('test.dtd'), context)
    1165
    1166          parser.resolvers.add(MyResolver())
    1167
    1168          xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
    1169          tree = parse(StringIO(xml), parser,
    1170                       base_url=fileInTestDir('__test.xml'))
    1171          root = tree.getroot()
    1172          self.assertEquals(
    1173              root.attrib,    {'default': 'valueA'})
    1174          self.assertEquals(
    1175              root[0].attrib, {'default': 'valueB'})
    1176
    1177 -    def test_resolve_file_dtd(self):
    1178          parse = self.etree.parse
    1179          parser = self.etree.XMLParser(attribute_defaults=True)
    1180          assertEqual = self.assertEqual
    1181          test_url = _str("__nosuch.dtd")
    1182
    1183          class MyResolver(self.etree.Resolver):
    1184              def resolve(self, url, id, context):
    1185                  assertEqual(url, test_url)
    1186                  return self.resolve_file(
    1187                      open(fileInTestDir('test.dtd'), 'rb'), context)
    1188
    1189          parser.resolvers.add(MyResolver())
    1190
    1191          xml = _str('<!DOCTYPE a SYSTEM "%s"><a><b/></a>') % test_url
    1192          tree = parse(StringIO(xml), parser)
    1193          root = tree.getroot()
    1194          self.assertEquals(
    1195              root.attrib,    {'default': 'valueA'})
    1196          self.assertEquals(
    1197              root[0].attrib, {'default': 'valueB'})
    1198
    1199 -    def test_resolve_empty(self):
    1200          parse = self.etree.parse
    1201          parser = self.etree.XMLParser(load_dtd=True)
    1202          assertEqual = self.assertEqual
    1203          test_url = _str("__nosuch.dtd")
    1204
    1205          class check(object):
    1206              resolved = False
    1207
    1208          class MyResolver(self.etree.Resolver):
    1209              def resolve(self, url, id, context):
    1210                  assertEqual(url, test_url)
    1211                  check.resolved = True
    1212                  return self.resolve_empty(context)
    1213
    1214          parser.resolvers.add(MyResolver())
    1215
    1216          xml = _str('<!DOCTYPE doc SYSTEM "%s"><doc>&myentity;</doc>') % test_url
    1217          self.assertRaises(etree.XMLSyntaxError, parse, StringIO(xml), parser)
    1218          self.assert_(check.resolved)
    1219
    1220 -    def test_resolve_error(self):
    1221          parse = self.etree.parse
    1222          parser = self.etree.XMLParser(dtd_validation=True)
    1223
    1224          class _LocalException(Exception):
    1225              pass
    1226
    1227          class MyResolver(self.etree.Resolver):
    1228              def resolve(self, url, id, context):
    1229                  raise _LocalException
    1230
    1231          parser.resolvers.add(MyResolver())
    1232
    1233          xml = '<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>'
    1234          self.assertRaises(_LocalException, parse, BytesIO(xml), parser)
    1235
    1236      if etree.LIBXML_VERSION > (2,6,20):
    1237 -        def test_entity_parse(self):
    1238              parse = self.etree.parse
    1239              tostring = self.etree.tostring
    1240              parser = self.etree.XMLParser(resolve_entities=False)
    1241              Entity = self.etree.Entity
    1242
    1243              xml = _bytes('<!DOCTYPE doc SYSTEM "test"><doc>&myentity;</doc>')
    1244              tree = parse(BytesIO(xml), parser)
    1245              root = tree.getroot()
    1246              self.assertEquals(root[0].tag, Entity)
    1247              self.assertEquals(root[0].text, "&myentity;")
    1248              self.assertEquals(root[0].tail, None)
    1249              self.assertEquals(root[0].name, "myentity")
    1250
    1251              self.assertEquals(_bytes('<doc>&myentity;</doc>'),
    1252                                tostring(root))
    1253
    1254 -        def test_entity_restructure(self):
    1255              xml = _bytes('''<!DOCTYPE root [ <!ENTITY nbsp "&#160;"> ]>
    1256                  <root>
    1257                    <child1/>
    1258                    <child2/>
    1259                    <child3>&nbsp;</child3>
    1260                  </root>''')
    1261
    1262              parser = self.etree.XMLParser(resolve_entities=False)
    1263              root = etree.fromstring(xml, parser)
    1264              self.assertEquals([ el.tag for el in root ],
    1265                                ['child1', 'child2', 'child3'])
    1266
    1267              root[0] = root[-1]
    1268              self.assertEquals([ el.tag for el in root ],
    1269                                ['child3', 'child2'])
    1270              self.assertEquals(root[0][0].text, '&nbsp;')
    1271              self.assertEquals(root[0][0].name, 'nbsp')
    1272
    1273 -    def test_entity_append(self):
    1274          Entity = self.etree.Entity
    1275          Element = self.etree.Element
    1276          tostring = self.etree.tostring
    1277
    1278          root = Element("root")
    1279          root.append( Entity("test") )
    1280
    1281          self.assertEquals(root[0].tag, Entity)
    1282          self.assertEquals(root[0].text, "&test;")
    1283          self.assertEquals(root[0].tail, None)
    1284          self.assertEquals(root[0].name, "test")
    1285
    1286          self.assertEquals(_bytes('<root>&test;</root>'),
    1287                            tostring(root))
    1288
    1289 -    def test_entity_values(self):
    1290          Entity = self.etree.Entity
    1291          self.assertEquals(Entity("test").text, '&test;')
    1292          self.assertEquals(Entity("#17683").text, '&#17683;')
    1293          self.assertEquals(Entity("#x1768").text, '&#x1768;')
    1294          self.assertEquals(Entity("#x98AF").text, '&#x98AF;')
    1295
    1296 -    def test_entity_error(self):
    1297          Entity = self.etree.Entity
    1298          self.assertRaises(ValueError, Entity, 'a b c')
    1299          self.assertRaises(ValueError, Entity, 'a,b')
    1300          self.assertRaises(ValueError, Entity, 'a\0b')
    1301          self.assertRaises(ValueError, Entity, '#abc')
    1302          self.assertRaises(ValueError, Entity, '#xxyz')
    1303
    1304 -    def test_cdata(self):
    1305          CDATA = self.etree.CDATA
    1306          Element = self.etree.Element
    1307          tostring = self.etree.tostring
    1308
    1309          root = Element("root")
    1310          root.text = CDATA('test')
    1311
    1312          self.assertEquals('test',
    1313                            root.text)
    1314          self.assertEquals(_bytes('<root><![CDATA[test]]></root>'),
    1315                            tostring(root))
    1316
    1317 -    def test_cdata_type(self):
    1318          CDATA = self.etree.CDATA
    1319          Element = self.etree.Element
    1320          root = Element("root")
    1321
    1322          root.text = CDATA("test")
    1323          self.assertEquals('test', root.text)
    1324
    1325          root.text = CDATA(_str("test"))
    1326          self.assertEquals('test', root.text)
    1327
    1328          self.assertRaises(TypeError, CDATA, 1)
    1329
    1330 -    def test_cdata_errors(self):
    1331          CDATA = self.etree.CDATA
    1332          Element = self.etree.Element
    1333
    1334          root = Element("root")
    1335          cdata = CDATA('test')
    1336
    1337          self.assertRaises(TypeError,
    1338                            setattr, root, 'tail', cdata)
    1339          self.assertRaises(TypeError,
    1340                            root.set, 'attr', cdata)
    1341          self.assertRaises(TypeError,
    1342                            operator.setitem, root.attrib, 'attr', cdata)
    1343
    1344 -    def test_cdata_parser(self):
    1345          tostring = self.etree.tostring
    1346          parser = self.etree.XMLParser(strip_cdata=False)
    1347          root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
    1348
    1349          self.assertEquals('test', root.text)
    1350          self.assertEquals(_bytes('<root><![CDATA[test]]></root>'),
    1351                            tostring(root))
    1352
    1353 -    def test_cdata_xpath(self):
    1354          tostring = self.etree.tostring
    1355          parser = self.etree.XMLParser(strip_cdata=False)
    1356          root = self.etree.XML(_bytes('<root><![CDATA[test]]></root>'), parser)
    1357          self.assertEquals(_bytes('<root><![CDATA[test]]></root>'),
    1358                            tostring(root))
    1359
    1360          self.assertEquals(['test'], root.xpath('//text()'))
    1361
    1362      # TypeError in etree, AssertionError in ElementTree;
    1363 -    def test_setitem_assert(self):
    1364          Element = self.etree.Element
    1365          SubElement = self.etree.SubElement
    1366
    1367          a = Element('a')
    1368          b = SubElement(a, 'b')
    1369
    1370          self.assertRaises(TypeError,
    1371                            a.__setitem__, 0, 'foo')
    1372
    1373 -    def test_append_error(self):
    1374          Element = self.etree.Element
    1375          root = Element('root')
    1376          # raises AssertionError in ElementTree
    1377          self.assertRaises(TypeError, root.append, None)
    1378          self.assertRaises(TypeError, root.extend, [None])
    1379          self.assertRaises(TypeError, root.extend, [Element('one'), None])
    1380          self.assertEquals('one', root[0].tag)
    1381
    1382 -    def test_addnext(self):
    1383          Element = self.etree.Element
    1384          SubElement = self.etree.SubElement
    1385          root = Element('root')
    1386          SubElement(root, 'a')
    1387          SubElement(root, 'b')
    1388
    1389          self.assertEquals(['a', 'b'],
    1390                            [c.tag for c in root])
    1391          root[1].addnext(root[0])
    1392          self.assertEquals(['b', 'a'],
    1393                            [c.tag for c in root])
    1394
    1395 -    def test_addprevious(self):
    1396          Element = self.etree.Element
    1397          SubElement = self.etree.SubElement
    1398          root = Element('root')
    1399          SubElement(root, 'a')
    1400          SubElement(root, 'b')
    1401
    1402          self.assertEquals(['a', 'b'],
    1403                            [c.tag for c in root])
    1404          root[0].addprevious(root[1])
    1405          self.assertEquals(['b', 'a'],
    1406                            [c.tag for c in root])
    1407
    1408 -    def test_addnext_root(self):
    1409          Element = self.etree.Element
    1410          a = Element('a')
    1411          b = Element('b')
    1412          self.assertRaises(TypeError, a.addnext, b)
    1413
    1414 -    def test_addnext_root(self):
    1415          Element = self.etree.Element
    1416          a = Element('a')
    1417          b = Element('b')
    1418          self.assertRaises(TypeError, a.addnext, b)
    1419
    1420 -    def test_addprevious_pi(self):
    1421          Element = self.etree.Element
    1422          SubElement = self.etree.SubElement
    1423          PI = self.etree.PI
    1424          root = Element('root')
    1425          SubElement(root, 'a')
    1426          pi = PI('TARGET', 'TEXT')
    1427          pi.tail = "TAIL"
    1428
    1429          self.assertEquals(_bytes('<root><a></a></root>'),
    1430                            self._writeElement(root))
    1431          root[0].addprevious(pi)
    1432          self.assertEquals(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'),
    1433                            self._writeElement(root))
    1434
    1435 -    def test_addprevious_root_pi(self):
    1436          Element = self.etree.Element
    1437          PI = self.etree.PI
    1438          root = Element('root')
    1439          pi = PI('TARGET', 'TEXT')
    1440          pi.tail = "TAIL"
    1441
    1442          self.assertEquals(_bytes('<root></root>'),
    1443                            self._writeElement(root))
    1444          root.addprevious(pi)
    1445          self.assertEquals(_bytes('<?TARGET TEXT?>\n<root></root>'),
    1446                            self._writeElement(root))
    1447
    1448 -    def test_addnext_pi(self):
    1449          Element = self.etree.Element
    1450          SubElement = self.etree.SubElement
    1451          PI = self.etree.PI
    1452          root = Element('root')
    1453          SubElement(root, 'a')
    1454          pi = PI('TARGET', 'TEXT')
    1455          pi.tail = "TAIL"
    1456
    1457          self.assertEquals(_bytes('<root><a></a></root>'),
    1458                            self._writeElement(root))
    1459          root[0].addnext(pi)
    1460          self.assertEquals(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'),
    1461                            self._writeElement(root))
    1462
    1463 -    def test_addnext_root_pi(self):
    1464          Element = self.etree.Element
    1465          PI = self.etree.PI
    1466          root = Element('root')
    1467          pi = PI('TARGET', 'TEXT')
    1468          pi.tail = "TAIL"
    1469
    1470          self.assertEquals(_bytes('<root></root>'),
    1471                            self._writeElement(root))
    1472          root.addnext(pi)
    1473          self.assertEquals(_bytes('<root></root>\n<?TARGET TEXT?>'),
    1474                            self._writeElement(root))
    1475
    1476 -    def test_addnext_comment(self):
    1477          Element = self.etree.Element
    1478          SubElement = self.etree.SubElement
    1479          Comment = self.etree.Comment
    1480          root = Element('root')
    1481          SubElement(root, 'a')
    1482          comment = Comment('TEXT ')
    1483          comment.tail = "TAIL"
    1484
    1485          self.assertEquals(_bytes('<root><a></a></root>'),
    1486                            self._writeElement(root))
    1487          root[0].addnext(comment)
    1488          self.assertEquals(_bytes('<root><a></a><!--TEXT -->TAIL</root>'),
    1489                            self._writeElement(root))
    1490
    1491 -    def test_addnext_root_comment(self):
    1492          Element = self.etree.Element
    1493          Comment = self.etree.Comment
    1494          root = Element('root')
    1495          comment = Comment('TEXT ')
    1496          comment.tail = "TAIL"
    1497
    1498          self.assertEquals(_bytes('<root></root>'),
    1499                            self._writeElement(root))
    1500          root.addnext(comment)
    1501          self.assertEquals(_bytes('<root></root>\n<!--TEXT -->'),
    1502                            self._writeElement(root))
    1503
    1504 -    def test_addprevious_comment(self):
    1505          Element = self.etree.Element
    1506          SubElement = self.etree.SubElement
    1507          Comment = self.etree.Comment
    1508          root = Element('root')
    1509          SubElement(root, 'a')
    1510          comment = Comment('TEXT ')
    1511          comment.tail = "TAIL"
    1512
    1513          self.assertEquals(_bytes('<root><a></a></root>'),
    1514                            self._writeElement(root))
    1515          root[0].addprevious(comment)
    1516          self.assertEquals(_bytes('<root><!--TEXT -->TAIL<a></a></root>'),
    1517                            self._writeElement(root))
    1518
    1519 -    def test_addprevious_root_comment(self):
    1520          Element = self.etree.Element
    1521          Comment = self.etree.Comment
    1522          root = Element('root')
    1523          comment = Comment('TEXT ')
    1524          comment.tail = "TAIL"
    1525
    1526          self.assertEquals(_bytes('<root></root>'),
    1527                            self._writeElement(root))
    1528          root.addprevious(comment)
    1529          self.assertEquals(_bytes('<!--TEXT -->\n<root></root>'),
    1530                            self._writeElement(root))
    1531
    1532      # ET's Elements have items() and key(), but not values()
    1533 -    def test_attribute_values(self):
    1534          XML = self.etree.XML
    1535
    1536          root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
    1537          values = root.values()
    1538          values.sort()
    1539          self.assertEquals(['Alpha', 'Beta', 'Gamma'], values)
    1540
    1541      # gives error in ElementTree
    1542 -    def test_comment_empty(self):
    1543          Element = self.etree.Element
    1544          Comment = self.etree.Comment
    1545
    1546          a = Element('a')
    1547          a.append(Comment())
    1548          self.assertEquals(
    1549              _bytes('<a><!----></a>'),
    1550              self._writeElement(a))
    1551
    1552      # ElementTree ignores comments
    1553 -    def test_comment_parse_empty(self):
    1554          ElementTree = self.etree.ElementTree
    1555          tostring = self.etree.tostring
    1556
    1557          xml = _bytes('<a><b/><!----><c/></a>')
    1558          f = BytesIO(xml)
    1559          doc = ElementTree(file=f)
    1560          a = doc.getroot()
    1561          self.assertEquals(
    1562              '',
    1563              a[1].text)
    1564          self.assertEquals(
    1565              xml,
    1566              tostring(a))
    1567
    1568      # ElementTree ignores comments
    1569 -    def test_comment_no_proxy_yet(self):
    1570          ElementTree = self.etree.ElementTree
    1571
    1572          f = BytesIO('<a><b></b><!-- hoi --><c></c></a>')
    1573          doc = ElementTree(file=f)
    1574          a = doc.getroot()
    1575          self.assertEquals(
    1576              ' hoi ',
    1577              a[1].text)
    1578
    1579      # does not raise an exception in ElementTree
    1580 -    def test_comment_immutable(self):
    1581          Element = self.etree.Element
    1582          Comment = self.etree.Comment
    1583
    1584          c = Comment()
    1585          el = Element('myel')
    1586
    1587          self.assertRaises(TypeError, c.append, el)
    1588          self.assertRaises(TypeError, c.insert, 0, el)
    1589          self.assertRaises(TypeError, c.set, "myattr", "test")
    1590
    1591      # test passing 'None' to dump
    1592 -    def test_dump_none(self):
    1593          self.assertRaises(TypeError, self.etree.dump, None)
    1594
    1595 -    def test_prefix(self):
    1596          ElementTree = self.etree.ElementTree
    1597
    1598          f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>')
    1599          doc = ElementTree(file=f)
    1600          a = doc.getroot()
    1601          self.assertEquals(
    1602              None,
    1603              a.prefix)
    1604          self.assertEquals(
    1605              'foo',
    1606              a[0].prefix)
    1607
    1608 -    def test_prefix_default_ns(self):
    1609          ElementTree = self.etree.ElementTree
    1610
    1611          f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>')
    1612          doc = ElementTree(file=f)
    1613          a = doc.getroot()
    1614          self.assertEquals(
    1615              None,
    1616              a.prefix)
    1617          self.assertEquals(
    1618              None,
    1619              a[0].prefix)
    1620
    1621 -    def test_getparent(self):
    1622          Element = self.etree.Element
    1623          SubElement = self.etree.SubElement
    1624
    1625          a = Element('a')
    1626          b = SubElement(a, 'b')
    1627          c = SubElement(a, 'c')
    1628          d = SubElement(b, 'd')
    1629          self.assertEquals(
    1630              None,
    1631              a.getparent())
    1632          self.assertEquals(
    1633              a,
    1634              b.getparent())
    1635          self.assertEquals(
    1636              b.getparent(),
    1637              c.getparent())
    1638          self.assertEquals(
    1639              b,
    1640              d.getparent())
    1641
    1642 -    def test_iterchildren(self):
    1643          XML = self.etree.XML
    1644
    1645          root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
    1646          result = []
    1647          for el in root.iterchildren():
    1648              result.append(el.tag)
    1649          self.assertEquals(['one', 'two', 'three'], result)
    1650
    1651 -    def test_iterchildren_reversed(self):
    1652          XML = self.etree.XML
    1653
    1654          root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
    1655          result = []
    1656          for el in root.iterchildren(reversed=True):
    1657              result.append(el.tag)
    1658          self.assertEquals(['three', 'two', 'one'], result)
    1659
    1660 -    def test_iterchildren_tag(self):
    1661          XML = self.etree.XML
    1662
    1663          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
    1664          result = []
    1665          for el in root.iterchildren(tag='two'):
    1666              result.append(el.text)
    1667          self.assertEquals(['Two', 'Bla'], result)
    1668
    1669 -    def test_iterchildren_tag_reversed(self):
    1670          XML = self.etree.XML
    1671
    1672          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
    1673          result = []
    1674          for el in root.iterchildren(reversed=True, tag='two'):
    1675              result.append(el.text)
    1676          self.assertEquals(['Bla', 'Two'], result)
    1677
    1678 -    def test_iterchildren_tag_multiple(self):
    1679          XML = self.etree.XML
    1680
    1681          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
    1682          result = []
    1683          for el in root.iterchildren(tag=['two', 'three']):
    1684              result.append(el.text)
    1685          self.assertEquals(['Two', 'Bla', None], result)
    1686
    1687 -    def test_iterchildren_tag_multiple_reversed(self):
    1688          XML = self.etree.XML
    1689
    1690          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two><three/></doc>'))
    1691          result = []
    1692          for el in root.iterchildren(reversed=True, tag=['two', 'three']):
    1693              result.append(el.text)
    1694          self.assertEquals([None, 'Bla', 'Two'], result)
    1695
    1696 -    def test_iterancestors(self):
    1697          Element    = self.etree.Element
    1698          SubElement = self.etree.SubElement
    1699
    1700          a = Element('a')
    1701          b = SubElement(a, 'b')
    1702          c = SubElement(a, 'c')
    1703          d = SubElement(b, 'd')
    1704          self.assertEquals(
    1705              [],
    1706              list(a.iterancestors()))
    1707          self.assertEquals(
    1708              [a],
    1709              list(b.iterancestors()))
    1710          self.assertEquals(
    1711              [a],
    1712              list(c.iterancestors()))
    1713          self.assertEquals(
    1714              [b, a],
    1715              list(d.iterancestors()))
    1716
    1717 -    def test_iterancestors_tag(self):
    1718          Element    = self.etree.Element
    1719          SubElement = self.etree.SubElement
    1720
    1721          a = Element('a')
    1722          b = SubElement(a, 'b')
    1723          c = SubElement(a, 'c')
    1724          d = SubElement(b, 'd')
    1725          self.assertEquals(
    1726              [a],
    1727              list(d.iterancestors(tag='a')))
    1728          self.assertEquals(
    1729              [b, a],
    1730                 list(d.iterancestors(tag='*')))
    1731
    1732 -    def test_iterancestors_tag_multiple(self):
    1733          Element    = self.etree.Element
    1734          SubElement = self.etree.SubElement
    1735
    1736          a = Element('a')
    1737          b = SubElement(a, 'b')
    1738          c = SubElement(a, 'c')
    1739          d = SubElement(b, 'd')
    1740          self.assertEquals(
    1741              [b, a],
    1742                 list(d.iterancestors(tag=('a', 'b'))))
    1743          self.assertEquals(
    1744              [],
    1745                 list(d.iterancestors(tag=('w', 'x', 'y', 'z'))))
    1746          self.assertEquals(
    1747              [],
    1748                list(d.iterancestors(tag=('d', 'x'))))
    1749          self.assertEquals(
    1750              [b, a],
    1751                list(d.iterancestors(tag=('b', '*'))))
    1752          self.assertEquals(
    1753              [b],
    1754                list(d.iterancestors(tag=('b', 'c'))))
    1755
    1756 -    def test_iterdescendants(self):
    1757          Element = self.etree.Element
    1758          SubElement = self.etree.SubElement
    1759
    1760          a = Element('a')
    1761          b = SubElement(a, 'b')
    1762          c = SubElement(a, 'c')
    1763          d = SubElement(b, 'd')
    1764          e = SubElement(c, 'e')
    1765
    1766          self.assertEquals(
    1767              [b, d, c, e],
    1768              list(a.iterdescendants()))
    1769          self.assertEquals(
    1770              [],
    1771              list(d.iterdescendants()))
    1772
    1773 -    def test_iterdescendants_tag(self):
    1774          Element = self.etree.Element
    1775          SubElement = self.etree.SubElement
    1776
    1777          a = Element('a')
    1778          b = SubElement(a, 'b')
    1779          c = SubElement(a, 'c')
    1780          d = SubElement(b, 'd')
    1781          e = SubElement(c, 'e')
    1782
    1783          self.assertEquals(
    1784              [],
    1785              list(a.iterdescendants('a')))
    1786          a2 = SubElement(e, 'a')
    1787          self.assertEquals(
    1788              [a2],
    1789              list(a.iterdescendants('a')))
    1790          self.assertEquals(
    1791              [a2],
    1792              list(c.iterdescendants('a')))
    1793
    1794 -    def test_iterdescendants_tag_multiple(self):
    1795          Element = self.etree.Element
    1796          SubElement = self.etree.SubElement
    1797
    1798          a = Element('a')
    1799          b = SubElement(a, 'b')
    1800          c = SubElement(a, 'c')
    1801          d = SubElement(b, 'd')
    1802          e = SubElement(c, 'e')
    1803
    1804          self.assertEquals(
    1805              [b, e],
    1806              list(a.iterdescendants(tag=('a', 'b', 'e'))))
    1807          a2 = SubElement(e, 'a')
    1808          self.assertEquals(
    1809              [b, a2],
    1810              list(a.iterdescendants(tag=('a', 'b'))))
    1811          self.assertEquals(
    1812              [],
    1813              list(c.iterdescendants(tag=('x', 'y', 'z'))))
    1814          self.assertEquals(
    1815              [b, d, c, e, a2],
    1816                list(a.iterdescendants(tag=('x', 'y', 'z', '*'))))
    1817
    1818 -    def test_getroottree(self):
    1819          Element = self.etree.Element
    1820          SubElement = self.etree.SubElement
    1821
    1822          a = Element('a')
    1823          b = SubElement(a, 'b')
    1824          c = SubElement(a, 'c')
    1825          d = SubElement(b, 'd')
    1826          self.assertEquals(
    1827              a,
    1828              a.getroottree().getroot())
    1829          self.assertEquals(
    1830              a,
    1831              b.getroottree().getroot())
    1832          self.assertEquals(
    1833              a,
    1834              d.getroottree().getroot())
    1835
    1836 -    def test_getnext(self):
    1837          Element    = self.etree.Element
    1838          SubElement = self.etree.SubElement
    1839
    1840          a = Element('a')
    1841          b = SubElement(a, 'b')
    1842          c = SubElement(a, 'c')
    1843          self.assertEquals(
    1844              None,
    1845              a.getnext())
    1846          self.assertEquals(
    1847              c,
    1848              b.getnext())
    1849          self.assertEquals(
    1850              None,
    1851              c.getnext())
    1852
    1853 -    def test_getprevious(self):
    1854          Element    = self.etree.Element
    1855          SubElement = self.etree.SubElement
    1856
    1857          a = Element('a')
    1858          b = SubElement(a, 'b')
    1859          c = SubElement(a, 'c')
    1860          d = SubElement(b, 'd')
    1861          self.assertEquals(
    1862              None,
    1863              a.getprevious())
    1864          self.assertEquals(
    1865              b,
    1866              c.getprevious())
    1867          self.assertEquals(
    1868              None,
    1869              b.getprevious())
    1870
    1871 -    def test_itersiblings(self):
    1872          Element    = self.etree.Element
    1873          SubElement = self.etree.SubElement
    1874
    1875          a = Element('a')
    1876          b = SubElement(a, 'b')
    1877          c = SubElement(a, 'c')
    1878          d = SubElement(b, 'd')
    1879          self.assertEquals(
    1880              [],
    1881              list(a.itersiblings()))
    1882          self.assertEquals(
    1883              [c],
    1884              list(b.itersiblings()))
    1885          self.assertEquals(
    1886              [],
    1887              list(c.itersiblings()))
    1888          self.assertEquals(
    1889              [b],
    1890              list(c.itersiblings(preceding=True)))
    1891          self.assertEquals(
    1892              [],
    1893              list(b.itersiblings(preceding=True)))
    1894
    1895 -    def test_itersiblings_tag(self):
    1896          Element    = self.etree.Element
    1897          SubElement = self.etree.SubElement
    1898
    1899          a = Element('a')
    1900          b = SubElement(a, 'b')
    1901          c = SubElement(a, 'c')
    1902          d = SubElement(b, 'd')
    1903          self.assertEquals(
    1904              [],
    1905              list(a.itersiblings(tag='XXX')))
    1906          self.assertEquals(
    1907              [c],
    1908              list(b.itersiblings(tag='c')))
    1909          self.assertEquals(
    1910              [c],
    1911              list(b.itersiblings(tag='*')))
    1912          self.assertEquals(
    1913              [b],
    1914              list(c.itersiblings(preceding=True, tag='b')))
    1915          self.assertEquals(
    1916              [],
    1917              list(c.itersiblings(preceding=True, tag='c')))
    1918
    1919 -    def test_itersiblings_tag_multiple(self):
    1920          Element    = self.etree.Element
    1921          SubElement = self.etree.SubElement
    1922
    1923          a = Element('a')
    1924          b = SubElement(a, 'b')
    1925          c = SubElement(a, 'c')
    1926          d = SubElement(b, 'd')
    1927          e = SubElement(a, 'e')
    1928          self.assertEquals(
    1929              [],
    1930              list(a.itersiblings(tag=('XXX', 'YYY'))))
    1931          self.assertEquals(
    1932              [c, e],
    1933              list(b.itersiblings(tag=('c', 'd', 'e'))))
    1934          self.assertEquals(
    1935              [b],
    1936              list(c.itersiblings(preceding=True, tag=('b', 'b', 'c', 'd'))))
    1937          self.assertEquals(
    1938              [c, b],
    1939              list(e.itersiblings(preceding=True, tag=('c', '*'))))
    1940
    1941 -    def test_parseid(self):
    1942          parseid = self.etree.parseid
    1943          XML     = self.etree.XML
    1944          xml_text = _bytes('''
    1945          <!DOCTYPE document [
    1946          <!ELEMENT document (h1,p)*>
    1947          <!ELEMENT h1 (#PCDATA)>
    1948          <!ATTLIST h1 myid ID #REQUIRED>
    1949          <!ELEMENT p  (#PCDATA)>
    1950          <!ATTLIST p  someid ID #REQUIRED>
    1951          ]>
    1952          <document>
    1953            <h1 myid="chapter1">...</h1>
    1954            <p id="note1" class="note">...</p>
    1955            <p>Regular paragraph.</p>
    1956            <p xml:id="xmlid">XML:ID paragraph.</p>
    1957            <p someid="warn1" class="warning">...</p>
    1958          </document>
    1959          ''')
    1960
    1961          tree, dic = parseid(BytesIO(xml_text))
    1962          root = tree.getroot()
    1963          root2 = XML(xml_text)
    1964          self.assertEquals(self._writeElement(root),
    1965                            self._writeElement(root2))
    1966          expected = {
    1967              "chapter1" : root[0],
    1968              "xmlid"    : root[3],
    1969              "warn1"    : root[4]
    1970              }
    1971          self.assert_("chapter1" in dic)
    1972          self.assert_("warn1" in dic)
    1973          self.assert_("xmlid" in dic)
    1974          self._checkIDDict(dic, expected)
    1975
    1976 -    def test_XMLDTDID(self):
    1977          XMLDTDID = self.etree.XMLDTDID
    1978          XML      = self.etree.XML
    1979          xml_text = _bytes('''
    1980          <!DOCTYPE document [
    1981          <!ELEMENT document (h1,p)*>
    1982          <!ELEMENT h1 (#PCDATA)>
    1983          <!ATTLIST h1 myid ID #REQUIRED>
    1984          <!ELEMENT p  (#PCDATA)>
    1985          <!ATTLIST p  someid ID #REQUIRED>
    1986          ]>
    1987          <document>
    1988            <h1 myid="chapter1">...</h1>
    1989            <p id="note1" class="note">...</p>
    1990            <p>Regular paragraph.</p>
    1991            <p xml:id="xmlid">XML:ID paragraph.</p>
    1992            <p someid="warn1" class="warning">...</p>
    1993          </document>
    1994          ''')
    1995
    1996          root, dic = XMLDTDID(xml_text)
    1997          root2 = XML(xml_text)
    1998          self.assertEquals(self._writeElement(root),
    1999                            self._writeElement(root2))
    2000          expected = {
    2001              "chapter1" : root[0],
    2002              "xmlid"    : root[3],
    2003              "warn1"    : root[4]
    2004              }
    2005          self.assert_("chapter1" in dic)
    2006          self.assert_("warn1" in dic)
    2007          self.assert_("xmlid" in dic)
    2008          self._checkIDDict(dic, expected)
    2009
    2010 -    def test_XMLDTDID_empty(self):
    2011          XMLDTDID = self.etree.XMLDTDID
    2012          XML      = self.etree.XML
    2013          xml_text = _bytes('''
    2014          <document>
    2015            <h1 myid="chapter1">...</h1>
    2016            <p id="note1" class="note">...</p>
    2017            <p>Regular paragraph.</p>
    2018            <p someid="warn1" class="warning">...</p>
    2019          </document>
    2020          ''')
    2021
    2022          root, dic = XMLDTDID(xml_text)
    2023          root2 = XML(xml_text)
    2024          self.assertEquals(self._writeElement(root),
    2025                            self._writeElement(root2))
    2026          expected = {}
    2027          self._checkIDDict(dic, expected)
    2028
    2029 -    def _checkIDDict(self, dic, expected):
    2030          self.assertEquals(len(dic),
    2031                            len(expected))
    2032          self.assertEquals(sorted(dic.items()),
    2033                            sorted(expected.items()))
    2034          if sys.version_info < (3,):
    2035              self.assertEquals(sorted(dic.iteritems()),
    2036                                sorted(expected.iteritems()))
    2037          self.assertEquals(sorted(dic.keys()),
    2038                            sorted(expected.keys()))
    2039          if sys.version_info < (3,):
    2040              self.assertEquals(sorted(dic.iterkeys()),
    2041                                sorted(expected.iterkeys()))
    2042          if sys.version_info < (3,):
    2043              self.assertEquals(sorted(dic.values()),
    2044                                sorted(expected.values()))
    2045              self.assertEquals(sorted(dic.itervalues()),
    2046                                sorted(expected.itervalues()))
    2047
    2048 -    def test_namespaces(self):
    2049          etree = self.etree
    2050
    2051          r = {'foo': 'http://ns.infrae.com/foo'}
    2052          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    2053          self.assertEquals(
    2054              'foo',
    2055              e.prefix)
    2056          self.assertEquals(
    2057              _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'),
    2058              self._writeElement(e))
    2059
    2060 -    def test_namespaces_default(self):
    2061          etree = self.etree
    2062
    2063          r = {None: 'http://ns.infrae.com/foo'}
    2064          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    2065          self.assertEquals(
    2066              None,
    2067              e.prefix)
    2068          self.assertEquals(
    2069              '{http://ns.infrae.com/foo}bar',
    2070              e.tag)
    2071          self.assertEquals(
    2072              _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'),
    2073              self._writeElement(e))
    2074
    2075 -    def test_namespaces_default_and_attr(self):
    2076          etree = self.etree
    2077
    2078          r = {None: 'http://ns.infrae.com/foo',
    2079               'hoi': 'http://ns.infrae.com/hoi'}
    2080          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    2081          e.set('{http://ns.infrae.com/hoi}test', 'value')
    2082          self.assertEquals(
    2083              _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'),
    2084              self._writeElement(e))
    2085
    2086 -    def test_namespaces_elementtree(self):
    2087          etree = self.etree
    2088          r = {None: 'http://ns.infrae.com/foo',
    2089               'hoi': 'http://ns.infrae.com/hoi'}
    2090          e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
    2091          tree = etree.ElementTree(element=e)
    2092          etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
    2093          self.assertEquals(
    2094              _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'),
    2095              self._writeElement(e))
    2096
    2097 -    def test_namespaces_default_copy_element(self):
    2098          etree = self.etree
    2099
    2100          r = {None: 'http://ns.infrae.com/foo'}
    2101          e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    2102          e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    2103
    2104          e1.append(e2)
    2105
    2106          self.assertEquals(
    2107              None,
    2108              e1.prefix)
    2109          self.assertEquals(
    2110              None,
    2111              e1[0].prefix)
    2112          self.assertEquals(
    2113              '{http://ns.infrae.com/foo}bar',
    2114              e1.tag)
    2115          self.assertEquals(
    2116              '{http://ns.infrae.com/foo}bar',
    2117              e1[0].tag)
    2118
    2119 -    def test_namespaces_copy_element(self):
    2120          etree = self.etree
    2121
    2122          r = {None: 'http://ns.infrae.com/BAR'}
    2123          e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
    2124          e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    2125
    2126          e1.append(e2)
    2127
    2128          self.assertEquals(
    2129              None,
    2130              e1.prefix)
    2131          self.assertNotEquals(
    2132              None,
    2133              e2.prefix)
    2134          self.assertEquals(
    2135              '{http://ns.infrae.com/BAR}bar',
    2136              e1.tag)
    2137          self.assertEquals(
    2138              '{http://ns.infrae.com/foo}bar',
    2139              e2.tag)
    2140
    2141 -    def test_namespaces_reuse_after_move(self):
    2142          ns_href = "http://a.b.c"
    2143          one = self.etree.fromstring(
    2144              _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
    2145          baz = one[0][0]
    2146
    2147          two = self.etree.fromstring(
    2148              _bytes('<root xmlns:ns="%s"/>' % ns_href))
    2149          two.append(baz)
    2150          del one # make sure the source document is deallocated
    2151
    2152          self.assertEquals('{%s}baz' % ns_href, baz.tag)
    2153          self.assertEquals(
    2154              _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href),
    2155              self.etree.tostring(two))
    2156
    2157 -    def test_namespace_cleanup(self):
    2158          xml = _bytes('<foo xmlns="F" xmlns:x="x"><bar xmlns:ns="NS" xmlns:b="b" xmlns="B"><ns:baz/></bar></foo>')
    2159          root = self.etree.fromstring(xml)
    2160          self.assertEquals(xml,
    2161                            self.etree.tostring(root))
    2162          self.etree.cleanup_namespaces(root)
    2163          self.assertEquals(
    2164              _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'),
    2165              self.etree.tostring(root))
    2166
    2167 -    def test_element_nsmap(self):
    2168          etree = self.etree
    2169
    2170          r = {None: 'http://ns.infrae.com/foo',
    2171               'hoi': 'http://ns.infrae.com/hoi'}
    2172          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    2173          self.assertEquals(
    2174              r,
    2175              e.nsmap)
    2176
    2177 -    def test_subelement_nsmap(self):
    2178          etree = self.etree
    2179
    2180          re = {None: 'http://ns.infrae.com/foo',
    2181               'hoi': 'http://ns.infrae.com/hoi'}
    2182          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
    2183
    2184          rs = {None: 'http://ns.infrae.com/honk',
    2185               'top': 'http://ns.infrae.com/top'}
    2186          s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
    2187
    2188          r = re.copy()
    2189          r.update(rs)
    2190          self.assertEquals(re, e.nsmap)
    2191          self.assertEquals(r,  s.nsmap)
    2192
    2193 -    def test_html_prefix_nsmap(self):
    2194          etree = self.etree
    2195          el = etree.HTML('<hha:page-description>aa</hha:page-description>').find('.//page-description')
    2196          self.assertEquals({'hha': None}, el.nsmap)
    2197
    2198 -    def test_getiterator_filter_multiple(self):
    2199          Element = self.etree.Element
    2200          SubElement = self.etree.SubElement
    2201
    2202          a = Element('a')
    2203          b = SubElement(a, 'b')
    2204          c = SubElement(a, 'c')
    2205          d = SubElement(b, 'd')
    2206          e = SubElement(c, 'e')
    2207          f = SubElement(c, 'f')
    2208
    2209          self.assertEquals(
    2210              [a, b],
    2211                 list(a.getiterator('a', 'b')))
    2212          self.assertEquals(
    2213              [],
    2214                list(a.getiterator('x', 'y')))
    2215          self.assertEquals(
    2216              [a, f],
    2217                list(a.getiterator('f', 'a')))
    2218          self.assertEquals(
    2219              [c, e, f],
    2220                 list(c.getiterator('c', '*', 'a')))
    2221          self.assertEquals(
    2222              [],
    2223                    list(a.getiterator( (), () )))
    2224
    2225 -    def test_getiterator_filter_multiple_tuple(self):
    2226          Element = self.etree.Element
    2227          SubElement = self.etree.SubElement
    2228
    2229          a = Element('a')
    2230          b = SubElement(a, 'b')
    2231          c = SubElement(a, 'c')
    2232          d = SubElement(b, 'd')
    2233          e = SubElement(c, 'e')
    2234          f = SubElement(c, 'f')
    2235
    2236          self.assertEquals(
    2237              [a, b],
    2238                    list(a.getiterator( ('a', 'b') )))
    2239          self.assertEquals(
    2240              [],
    2241                list(a.getiterator( ('x', 'y') )))
    2242          self.assertEquals(
    2243              [a, f],
    2244                    list(a.getiterator( ('f', 'a') )))
    2245          self.assertEquals(
    2246              [c, e, f],
    2247                       list(c.getiterator( ('c', '*', 'a') )))
    2248          self.assertEquals(
    2249              [],
    2250                list(a.getiterator( () )))
    2251
    2252 -    def test_getiterator_filter_namespace(self):
    2253          Element = self.etree.Element
    2254          SubElement = self.etree.SubElement
    2255
    2256          a = Element('{a}a')
    2257          b = SubElement(a, '{a}b')
    2258          c = SubElement(a, '{a}c')
    2259          d = SubElement(b, '{b}d')
    2260          e = SubElement(c, '{a}e')
    2261          f = SubElement(c, '{b}f')
    2262          g = SubElement(c, 'g')
    2263
    2264          self.assertEquals(
    2265              [a],
    2266              list(a.getiterator('{a}a')))
    2267          self.assertEquals(
    2268              [],
    2269              list(a.getiterator('{b}a')))
    2270          self.assertEquals(
    2271              [],
    2272              list(a.getiterator('a')))
    2273          self.assertEquals(
    2274              [a,b,d,c,e,f,g],
    2275              list(a.getiterator('*')))
    2276          self.assertEquals(
    2277              [f],
    2278              list(c.getiterator('{b}*')))
    2279          self.assertEquals(
    2280              [d, f],
    2281              list(a.getiterator('{b}*')))
    2282          self.assertEquals(
    2283              [g],
    2284              list(a.getiterator('g')))
    2285          self.assertEquals(
    2286              [g],
    2287              list(a.getiterator('{}g')))
    2288          self.assertEquals(
    2289              [g],
    2290              list(a.getiterator('{}*')))
    2291
    2292 -    def test_getiterator_filter_local_name(self):
    2293          Element = self.etree.Element
    2294          SubElement = self.etree.SubElement
    2295
    2296          a = Element('{a}a')
    2297          b = SubElement(a, '{nsA}b')
    2298          c = SubElement(b, '{nsB}b')
    2299          d = SubElement(a, 'b')
    2300          e = SubElement(a, '{nsA}e')
    2301          f = SubElement(e, '{nsB}e')
    2302          g = SubElement(e, 'e')
    2303
    2304          self.assertEquals(
    2305              [b, c, d],
    2306              list(a.getiterator('{*}b')))
    2307          self.assertEquals(
    2308              [e, f, g],
    2309              list(a.getiterator('{*}e')))
    2310          self.assertEquals(
    2311              [a, b, c, d, e, f, g],
    2312              list(a.getiterator('{*}*')))
    2313
    2314 -    def test_getiterator_filter_entities(self):
    2315          Element = self.etree.Element
    2316          Entity = self.etree.Entity
    2317          SubElement = self.etree.SubElement
    2318
    2319          a = Element('a')
    2320          b = SubElement(a, 'b')
    2321          entity_b = Entity("TEST-b")
    2322          b.append(entity_b)
    2323
    2324          self.assertEquals(
    2325              [entity_b],
    2326              list(a.getiterator(Entity)))
    2327
    2328          entity_a = Entity("TEST-a")
    2329          a.append(entity_a)
    2330
    2331          self.assertEquals(
    2332              [entity_b, entity_a],
    2333              list(a.getiterator(Entity)))
    2334
    2335          self.assertEquals(
    2336              [entity_b],
    2337              list(b.getiterator(Entity)))
    2338
    2339 -    def test_getiterator_filter_element(self):
    2340          Element = self.etree.Element
    2341          Comment = self.etree.Comment
    2342          PI = self.etree.PI
    2343          SubElement = self.etree.SubElement
    2344
    2345          a = Element('a')
    2346          b = SubElement(a, 'b')
    2347          a.append(Comment("test"))
    2348          a.append(PI("pi", "content"))
    2349          c = SubElement(a, 'c')
    2350
    2351          self.assertEquals(
    2352              [a, b, c],
    2353              list(a.getiterator(Element)))
    2354
    2355 -    def test_getiterator_filter_all_comment_pi(self):
    2356          # ElementTree iterates over everything here
    2357          Element = self.etree.Element
    2358          Comment = self.etree.Comment
    2359          PI = self.etree.PI
    2360          SubElement = self.etree.SubElement
    2361
    2362          a = Element('a')
    2363          b = SubElement(a, 'b')
    2364          a.append(Comment("test"))
    2365          a.append(PI("pi", "content"))
    2366          c = SubElement(a, 'c')
    2367
    2368          self.assertEquals(
    2369              [a, b, c],
    2370              list(a.getiterator('*')))
    2371
    2372 -    def test_elementtree_find_qname(self):
    2373          XML = self.etree.XML
    2374          ElementTree = self.etree.ElementTree
    2375          QName = self.etree.QName
    2376          tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
    2377          self.assertEquals(tree.find(QName("c")), tree.getroot()[2])
    2378
    2379 -    def test_elementtree_findall_qname(self):
    2380          XML = self.etree.XML
    2381          ElementTree = self.etree.ElementTree
    2382          QName = self.etree.QName
    2383          tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
    2384          self.assertEquals(len(list(tree.findall(QName("c")))), 1)
    2385
    2386 -    def test_elementtree_findall_ns_qname(self):
    2387          XML = self.etree.XML
    2388          ElementTree = self.etree.ElementTree
    2389          QName = self.etree.QName
    2390          tree = ElementTree(XML(
    2391                  _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')))
    2392          self.assertEquals(len(list(tree.findall(QName("b")))), 2)
    2393          self.assertEquals(len(list(tree.findall(QName("X", "b")))), 1)
    2394
    2395 -    def test_findall_ns(self):
    2396          XML = self.etree.XML
    2397          root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
    2398          self.assertEquals(len(root.findall(".//{X}b")), 2)
    2399          self.assertEquals(len(root.findall(".//{X}*")), 2)
    2400          self.assertEquals(len(root.findall(".//b")), 3)
    2401
    2402 -    def test_findall_syntax_error(self):
    2403          XML = self.etree.XML
    2404          root = XML(_bytes('<a><b><c/></b><b/><c><b/><b/></c><b/></a>'))
    2405          self.assertRaises(SyntaxError, root.findall, '')
    2406          self.assertRaises(SyntaxError, root.findall, '//')  # absolute path on Element
    2407          self.assertRaises(SyntaxError, root.findall, './//')
    2408
    2409 -    def test_index(self):
    2410          etree = self.etree
    2411          e = etree.Element('foo')
    2412          for i in range(10):
    2413              etree.SubElement(e, 'a%s' % i)
    2414          for i in range(10):
    2415              self.assertEquals(
    2416                  i,
    2417                  e.index(e[i]))
    2418          self.assertEquals(
    2419              3, e.index(e[3], 3))
    2420          self.assertRaises(
    2421              ValueError, e.index, e[3], 4)
    2422          self.assertRaises(
    2423              ValueError, e.index, e[3], 0, 2)
    2424          self.assertRaises(
    2425              ValueError, e.index, e[8], 0, -3)
    2426          self.assertRaises(
    2427              ValueError, e.index, e[8], -5, -3)
    2428          self.assertEquals(
    2429              8, e.index(e[8], 0, -1))
    2430          self.assertEquals(
    2431              8, e.index(e[8], -12, -1))
    2432          self.assertEquals(
    2433              0, e.index(e[0], -12, -1))
    2434
    2435 -    def test_replace(self):
    2436          etree = self.etree
    2437          e = etree.Element('foo')
    2438          for i in range(10):
    2439              el = etree.SubElement(e, 'a%s' % i)
    2440              el.text = "text%d" % i
    2441              el.tail = "tail%d" % i
    2442
    2443          child0 = e[0]
    2444          child1 = e[1]
    2445          child2 = e[2]
    2446
    2447          e.replace(e[0], e[1])
    2448          self.assertEquals(
    2449              9, len(e))
    2450          self.assertEquals(
    2451              child1, e[0])
    2452          self.assertEquals(
    2453              child1.text, "text1")
    2454          self.assertEquals(
    2455              child1.tail, "tail1")
    2456          self.assertEquals(
    2457              child0.tail, "tail0")
    2458          self.assertEquals(
    2459              child2, e[1])
    2460
    2461          e.replace(e[-1], e[0])
    2462          self.assertEquals(
    2463              child1, e[-1])
    2464          self.assertEquals(
    2465              child1.text, "text1")
    2466          self.assertEquals(
    2467              child1.tail, "tail1")
    2468          self.assertEquals(
    2469              child2, e[0])
    2470
    2471 -    def test_replace_new(self):
    2472          etree = self.etree
    2473          e = etree.Element('foo')
    2474          for i in range(10):
    2475              etree.SubElement(e, 'a%s' % i)
    2476
    2477          new_element = etree.Element("test")
    2478          new_element.text = "TESTTEXT"
    2479          new_element.tail = "TESTTAIL"
    2480          child1 = e[1]
    2481          e.replace(e[0], new_element)
    2482          self.assertEquals(
    2483              new_element, e[0])
    2484          self.assertEquals(
    2485              "TESTTEXT",
    2486              e[0].text)
    2487          self.assertEquals(
    2488              "TESTTAIL",
    2489              e[0].tail)
    2490          self.assertEquals(
    2491              child1, e[1])
    2492
    2493 -    def test_setslice_all_empty_reversed(self):
    2494          Element = self.etree.Element
    2495          SubElement = self.etree.SubElement
    2496
    2497          a = Element('a')
    2498
    2499          e = Element('e')
    2500          f = Element('f')
    2501          g = Element('g')
    2502
    2503          s = [e, f, g]
    2504          a[::-1] = s
    2505          self.assertEquals(
    2506              [g, f, e],
    2507              list(a))
    2508
    2509 -    def test_setslice_step(self):
    2510          Element = self.etree.Element
    2511          SubElement = self.etree.SubElement
    2512
    2513          a = Element('a')
    2514          b = SubElement(a, 'b')
    2515          c = SubElement(a, 'c')
    2516          d = SubElement(a, 'd')
    2517          e = SubElement(a, 'e')
    2518
    2519          x = Element('x')
    2520          y = Element('y')
    2521
    2522          a[1::2] = [x, y]
    2523          self.assertEquals(
    2524              [b, x, d, y],
    2525              list(a))
    2526
    2527 -    def test_setslice_step_negative(self):
    2528          Element = self.etree.Element
    2529          SubElement = self.etree.SubElement
    2530
    2531          a = Element('a')
    2532          b = SubElement(a, 'b')
    2533          c = SubElement(a, 'c')
    2534          d = SubElement(a, 'd')
    2535          e = SubElement(a, 'e')
    2536
    2537          x = Element('x')
    2538          y = Element('y')
    2539
    2540          a[1::-1] = [x, y]
    2541          self.assertEquals(
    2542              [y, x, d, e],
    2543              list(a))
    2544
    2545 -    def test_setslice_step_negative2(self):
    2546          Element = self.etree.Element
    2547          SubElement = self.etree.SubElement
    2548
    2549          a = Element('a')
    2550          b = SubElement(a, 'b')
    2551          c = SubElement(a, 'c')
    2552          d = SubElement(a, 'd')
    2553          e = SubElement(a, 'e')
    2554
    2555          x = Element('x')
    2556          y = Element('y')
    2557
    2558          a[::-2] = [x, y]
    2559          self.assertEquals(
    2560              [b, y, d, x],
    2561              list(a))
    2562
    2563 -    def test_setslice_step_overrun(self):
    2564          Element = self.etree.Element
    2565          SubElement = self.etree.SubElement
    2566          try:
    2567              slice
    2568          except NameError:
    2569              print("slice() not found")
    2570              return
    2571
    2572          a = Element('a')
    2573          b = SubElement(a, 'b')
    2574          c = SubElement(a, 'c')
    2575          d = SubElement(a, 'd')
    2576          e = SubElement(a, 'e')
    2577
    2578          x = Element('x')
    2579          y = Element('y')
    2580          z = Element('z')
    2581
    2582          self.assertRaises(
    2583              ValueError,
    2584              operator.setitem, a, slice(1,None,2), [x, y, z])
    2585
    2586          self.assertEquals(
    2587              [b, c, d, e],
    2588              list(a))
    2589
    2590 -    def test_sourceline_XML(self):
    2591          XML = self.etree.XML
    2592          root = XML(_bytes('''<?xml version="1.0"?>
    2593          <root><test>
    2594
    2595          <bla/></test>
    2596          </root>
    2597          '''))
    2598
    2599          self.assertEquals(
    2600              [2, 2, 4],
    2601              [ el.sourceline for el in root.getiterator() ])
    2602
    2603 -    def test_sourceline_parse(self):
    2604          parse = self.etree.parse
    2605          tree = parse(fileInTestDir('include/test_xinclude.xml'))
    2606
    2607          self.assertEquals(
    2608              [1, 2, 3],
    2609              [ el.sourceline for el in tree.getiterator() ])
    2610
    2611 -    def test_sourceline_iterparse_end(self):
    2612          iterparse = self.etree.iterparse
    2613          lines = [ el.sourceline for (event, el) in
    2614                    iterparse(fileInTestDir('include/test_xinclude.xml')) ]
    2615
    2616          self.assertEquals(
    2617              [2, 3, 1],
    2618              lines)
    2619
    2620 -    def test_sourceline_iterparse_start(self):
    2621          iterparse = self.etree.iterparse
    2622          lines = [ el.sourceline for (event, el) in
    2623                    iterparse(fileInTestDir('include/test_xinclude.xml'),
    2624                              events=("start",)) ]
    2625
    2626          self.assertEquals(
    2627              [1, 2, 3],
    2628              lines)
    2629
    2630 -    def test_sourceline_element(self):
    2631          Element = self.etree.Element
    2632          SubElement = self.etree.SubElement
    2633          el = Element("test")
    2634          self.assertEquals(None, el.sourceline)
    2635
    2636          child = SubElement(el, "test")
    2637          self.assertEquals(None, el.sourceline)
    2638          self.assertEquals(None, child.sourceline)
    2639
    2640 -    def test_XML_base_url_docinfo(self):
    2641          etree = self.etree
    2642          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2643          docinfo = root.getroottree().docinfo
    2644          self.assertEquals(docinfo.URL, "http://no/such/url")
    2645
    2646 -    def test_XML_set_base_url_docinfo(self):
    2647          etree = self.etree
    2648          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2649          docinfo = root.getroottree().docinfo
    2650          self.assertEquals(docinfo.URL, "http://no/such/url")
    2651          docinfo.URL = "https://secret/url"
    2652          self.assertEquals(docinfo.URL, "https://secret/url")
    2653
    2654 -    def test_parse_stringio_base_url(self):
    2655          etree = self.etree
    2656          tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url")
    2657          docinfo = tree.docinfo
    2658          self.assertEquals(docinfo.URL, "http://no/such/url")
    2659
    2660 -    def test_parse_base_url_docinfo(self):
    2661          etree = self.etree
    2662          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
    2663                             base_url="http://no/such/url")
    2664          docinfo = tree.docinfo
    2665          self.assertEquals(docinfo.URL, "http://no/such/url")
    2666
    2667 -    def test_HTML_base_url_docinfo(self):
    2668          etree = self.etree
    2669          root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url")
    2670          docinfo = root.getroottree().docinfo
    2671          self.assertEquals(docinfo.URL, "http://no/such/url")
    2672
    2673 -    def test_docinfo_public(self):
    2674          etree = self.etree
    2675          xml_header = '<?xml version="1.0" encoding="ascii"?>'
    2676          pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
    2677          sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    2678          doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
    2679
    2680          xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
    2681
    2682          tree = etree.parse(BytesIO(xml))
    2683          docinfo = tree.docinfo
    2684          self.assertEquals(docinfo.encoding,    "ascii")
    2685          self.assertEquals(docinfo.xml_version, "1.0")
    2686          self.assertEquals(docinfo.public_id,   pub_id)
    2687          self.assertEquals(docinfo.system_url,  sys_id)
    2688          self.assertEquals(docinfo.root_name,   'html')
    2689          self.assertEquals(docinfo.doctype, doctype_string)
    2690
    2691 -    def test_docinfo_system(self):
    2692          etree = self.etree
    2693          xml_header = '<?xml version="1.0" encoding="UTF-8"?>'
    2694          sys_id = "some.dtd"
    2695          doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id
    2696          xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
    2697
    2698          tree = etree.parse(BytesIO(xml))
    2699          docinfo = tree.docinfo
    2700          self.assertEquals(docinfo.encoding,    "UTF-8")
    2701          self.assertEquals(docinfo.xml_version, "1.0")
    2702          self.assertEquals(docinfo.public_id,   None)
    2703          self.assertEquals(docinfo.system_url,  sys_id)
    2704          self.assertEquals(docinfo.root_name,   'html')
    2705          self.assertEquals(docinfo.doctype, doctype_string)
    2706
    2707 -    def test_docinfo_empty(self):
    2708          etree = self.etree
    2709          xml = _bytes('<html><body></body></html>')
    2710          tree = etree.parse(BytesIO(xml))
    2711          docinfo = tree.docinfo
    2712          self.assertEquals(docinfo.encoding,    "UTF-8")
    2713          self.assertEquals(docinfo.xml_version, "1.0")
    2714          self.assertEquals(docinfo.public_id,   None)
    2715          self.assertEquals(docinfo.system_url,  None)
    2716          self.assertEquals(docinfo.root_name,   'html')
    2717          self.assertEquals(docinfo.doctype, '')
    2718
    2719 -    def test_docinfo_name_only(self):
    2720          etree = self.etree
    2721          xml = _bytes('<!DOCTYPE root><root></root>')
    2722          tree = etree.parse(BytesIO(xml))
    2723          docinfo = tree.docinfo
    2724          self.assertEquals(docinfo.encoding,    "UTF-8")
    2725          self.assertEquals(docinfo.xml_version, "1.0")
    2726          self.assertEquals(docinfo.public_id,   None)
    2727          self.assertEquals(docinfo.system_url,  None)
    2728          self.assertEquals(docinfo.root_name,   'root')
    2729          self.assertEquals(docinfo.doctype, '<!DOCTYPE root>')
    2730
    2731 -    def test_doctype_name_only_roundtrip(self):
    2732          etree = self.etree
    2733          xml = _bytes('<!DOCTYPE root>\n<root/>')
    2734          tree = etree.parse(BytesIO(xml))
    2735          self.assertEquals(xml, etree.tostring(tree))
    2736
    2737 -    def test_doctype_output_override(self):
    2738          etree = self.etree
    2739          pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
    2740          sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    2741          doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
    2742
    2743          xml = _bytes('<!DOCTYPE root>\n<root/>')
    2744          tree = etree.parse(BytesIO(xml))
    2745          self.assertEquals(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
    2746                            etree.tostring(tree, doctype=doctype_string))
    2747
    2748 -    def test_xml_base(self):
    2749          etree = self.etree
    2750          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2751          self.assertEquals(root.base, "http://no/such/url")
    2752          self.assertEquals(
    2753              root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
    2754          root.base = "https://secret/url"
    2755          self.assertEquals(root.base, "https://secret/url")
    2756          self.assertEquals(
    2757              root.get('{http://www.w3.org/XML/1998/namespace}base'),
    2758              "https://secret/url")
    2759
    2760 -    def test_xml_base_attribute(self):
    2761          etree = self.etree
    2762          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2763          self.assertEquals(root.base, "http://no/such/url")
    2764          self.assertEquals(
    2765              root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
    2766          root.set('{http://www.w3.org/XML/1998/namespace}base',
    2767                   "https://secret/url")
    2768          self.assertEquals(root.base, "https://secret/url")
    2769          self.assertEquals(
    2770              root.get('{http://www.w3.org/XML/1998/namespace}base'),
    2771              "https://secret/url")
    2772
    2773 -    def test_html_base(self):
    2774          etree = self.etree
    2775          root = etree.HTML(_bytes("<html><body></body></html>"),
    2776                            base_url="http://no/such/url")
    2777          self.assertEquals(root.base, "http://no/such/url")
    2778
    2779 -    def test_html_base_tag(self):
    2780          etree = self.etree
    2781          root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>'))
    2782          self.assertEquals(root.base, "http://no/such/url")
    2783
    2784 -    def test_parse_fileobject_unicode(self):
    2785          # parse from a file object that returns unicode strings
    2786          f = LargeFileLikeUnicode()
    2787          tree = self.etree.parse(f)
    2788          root = tree.getroot()
    2789          self.assert_(root.tag.endswith('root'))
    2790
    2791 -    def test_dtd_io(self):
    2792          # check that DTDs that go in also go back out
    2793          xml = _bytes('''\
    2794          <!DOCTYPE test SYSTEM "test.dtd" [
    2795            <!ENTITY entity "tasty">
    2796            <!ELEMENT test (a)>
    2797            <!ELEMENT a (#PCDATA)>
    2798          ]>
    2799          <test><a>test-test</a></test>\
    2800          ''')
    2801          tree = self.etree.parse(BytesIO(xml))
    2802          self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")),
    2803                           xml.replace(_bytes(" "), _bytes("")))
    2804
    2805 -    def test_byte_zero(self):
    2806          Element = self.etree.Element
    2807
    2808          a = Element('a')
    2809          self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
    2810          self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
    2811
    2812          self.assertRaises(ValueError, Element, 'ha\0ho')
    2813
    2814 -    def test_unicode_byte_zero(self):
    2815          Element = self.etree.Element
    2816
    2817          a = Element('a')
    2818          self.assertRaises(ValueError, setattr, a, "text",
    2819                            _str('ha\0ho'))
    2820          self.assertRaises(ValueError, setattr, a, "tail",
    2821                            _str('ha\0ho'))
    2822
    2823          self.assertRaises(ValueError, Element,
    2824                            _str('ha\0ho'))
    2825
    2826 -    def test_byte_invalid(self):
    2827          Element = self.etree.Element
    2828
    2829          a = Element('a')
    2830          self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
    2831          self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
    2832
    2833          self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
    2834          self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
    2835
    2836          self.assertRaises(ValueError, Element, 'ha\x07ho')
    2837          self.assertRaises(ValueError, Element, 'ha\x02ho')
    2838
    2839 -    def test_unicode_byte_invalid(self):
    2840          Element = self.etree.Element
    2841
    2842          a = Element('a')
    2843          self.assertRaises(ValueError, setattr, a, "text",
    2844                            _str('ha\x07ho'))
    2845          self.assertRaises(ValueError, setattr, a, "text",
    2846                            _str('ha\x02ho'))
    2847
    2848          self.assertRaises(ValueError, setattr, a, "tail",
    2849                            _str('ha\x07ho'))
    2850          self.assertRaises(ValueError, setattr, a, "tail",
    2851                            _str('ha\x02ho'))
    2852
    2853          self.assertRaises(ValueError, Element,
    2854                            _str('ha\x07ho'))
    2855          self.assertRaises(ValueError, Element,
    2856                            _str('ha\x02ho'))
    2857
    2858 -    def test_unicode_byte_invalid_sequence(self):
    2859          Element = self.etree.Element
    2860
    2861          a = Element('a')
    2862          self.assertRaises(ValueError, setattr, a, "text",
    2863                            _str('ha\u1234\x07ho'))
    2864          self.assertRaises(ValueError, setattr, a, "text",
    2865                            _str('ha\u1234\x02ho'))
    2866
    2867          self.assertRaises(ValueError, setattr, a, "tail",
    2868                            _str('ha\u1234\x07ho'))
    2869          self.assertRaises(ValueError, setattr, a, "tail",
    2870                            _str('ha\u1234\x02ho'))
    2871
    2872          self.assertRaises(ValueError, Element,
    2873                            _str('ha\u1234\x07ho'))
    2874          self.assertRaises(ValueError, Element,
    2875                            _str('ha\u1234\x02ho'))
    2876
    2877 -    def test_encoding_tostring_utf16(self):
    2878          # ElementTree fails to serialize this
    2879          tostring = self.etree.tostring
    2880          Element = self.etree.Element
    2881          SubElement = self.etree.SubElement
    2882
    2883          a = Element('a')
    2884          b = SubElement(a, 'b')
    2885          c = SubElement(a, 'c')
    2886
    2887          result = tostring(a, encoding='UTF-16')
    2888          self.assertEquals(_bytes('<a><b></b><c></c></a>'),
    2889                            canonicalize(result))
    2890
    2891 -    def test_tostring_none(self):
    2892          # ElementTree raises an AssertionError here
    2893          tostring = self.etree.tostring
    2894          self.assertRaises(TypeError, self.etree.tostring, None)
    2895
    2896 -    def test_tostring_pretty(self):
    2897          tostring = self.etree.tostring
    2898          Element = self.etree.Element
    2899          SubElement = self.etree.SubElement
    2900
    2901          a = Element('a')
    2902          b = SubElement(a, 'b')
    2903          c = SubElement(a, 'c')
    2904
    2905          result = tostring(a)
    2906          self.assertEquals(result, _bytes("<a><b/><c/></a>"))
    2907
    2908          result = tostring(a, pretty_print=False)
    2909          self.assertEquals(result, _bytes("<a><b/><c/></a>"))
    2910
    2911          result = tostring(a, pretty_print=True)
    2912          self.assertEquals(result, _bytes("<a>\n  <b/>\n  <c/>\n</a>\n"))
    2913
    2914 -    def test_tostring_with_tail(self):
    2915          tostring = self.etree.tostring
    2916          Element = self.etree.Element
    2917          SubElement = self.etree.SubElement
    2918
    2919          a = Element('a')
    2920          a.tail = "aTAIL"
    2921          b = SubElement(a, 'b')
    2922          b.tail = "bTAIL"
    2923          c = SubElement(a, 'c')
    2924
    2925          result = tostring(a)
    2926          self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
    2927
    2928          result = tostring(a, with_tail=False)
    2929          self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>"))
    2930
    2931          result = tostring(a, with_tail=True)
    2932          self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
    2933
    2934 -    def test_standalone(self):
    2935          tostring = self.etree.tostring
    2936          XML = self.etree.XML
    2937          ElementTree = self.etree.ElementTree
    2938          Element = self.etree.Element
    2939
    2940          tree = Element("root").getroottree()
    2941          self.assertEquals(None, tree.docinfo.standalone)
    2942
    2943          tree = XML(_bytes("<root/>")).getroottree()
    2944          self.assertEquals(None, tree.docinfo.standalone)
    2945
    2946          tree = XML(_bytes(
    2947              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"
    2948              )).getroottree()
    2949          self.assertEquals(True, tree.docinfo.standalone)
    2950
    2951          tree = XML(_bytes(
    2952              "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"
    2953              )).getroottree()
    2954          self.assertEquals(False, tree.docinfo.standalone)
    2955
    2956 -    def test_tostring_standalone(self):
    2957          tostring = self.etree.tostring
    2958          XML = self.etree.XML
    2959          ElementTree = self.etree.ElementTree
    2960
    2961          root = XML(_bytes("<root/>"))
    2962
    2963          tree = ElementTree(root)
    2964          self.assertEquals(None, tree.docinfo.standalone)
    2965
    2966          result = tostring(root, xml_declaration=True, encoding="ASCII")
    2967          self.assertEquals(result, _bytes(
    2968              "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
    2969
    2970          result = tostring(root, xml_declaration=True, encoding="ASCII",
    2971                            standalone=True)
    2972          self.assertEquals(result, _bytes(
    2973              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
    2974
    2975          tree = ElementTree(XML(result))
    2976          self.assertEquals(True, tree.docinfo.standalone)
    2977
    2978          result = tostring(root, xml_declaration=True, encoding="ASCII",
    2979                            standalone=False)
    2980          self.assertEquals(result, _bytes(
    2981              "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
    2982
    2983          tree = ElementTree(XML(result))
    2984          self.assertEquals(False, tree.docinfo.standalone)
    2985
    2986 -    def test_tostring_standalone_in_out(self):
    2987          tostring = self.etree.tostring
    2988          XML = self.etree.XML
    2989          ElementTree = self.etree.ElementTree
    2990
    2991          root = XML(_bytes(
    2992              "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>"))
    2993
    2994          tree = ElementTree(root)
    2995          self.assertEquals(True, tree.docinfo.standalone)
    2996
    2997          result = tostring(root, xml_declaration=True, encoding="ASCII")
    2998          self.assertEquals(result, _bytes(
    2999              "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
    3000
    3001          result = tostring(root, xml_declaration=True, encoding="ASCII",
    3002                            standalone=True)
    3003          self.assertEquals(result, _bytes(
    3004              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
    3005
    3006 -    def test_tostring_method_text_encoding(self):
    3007          tostring = self.etree.tostring
    3008          Element = self.etree.Element
    3009          SubElement = self.etree.SubElement
    3010
    3011          a = Element('a')
    3012          a.text = "A"
    3013          a.tail = "tail"
    3014          b = SubElement(a, 'b')
    3015          b.text = "B"
    3016          b.tail = _str("Søk på nettet")
    3017          c = SubElement(a, 'c')
    3018          c.text = "C"
    3019
    3020          result = tostring(a, method="text", encoding="UTF-16")
    3021
    3022          self.assertEquals(_str('ABSøk på nettetCtail').encode("UTF-16"),
    3023                            result)
    3024
    3025 -    def test_tostring_method_text_unicode(self):
    3026          tostring = self.etree.tostring
    3027          Element = self.etree.Element
    3028          SubElement = self.etree.SubElement
    3029
    3030          a = Element('a')
    3031          a.text = _str('Søk på nettetA')
    3032          a.tail = "tail"
    3033          b = SubElement(a, 'b')
    3034          b.text = "B"
    3035          b.tail = _str('Søk på nettetB')
    3036          c = SubElement(a, 'c')
    3037          c.text = "C"
    3038
    3039          self.assertRaises(UnicodeEncodeError,
    3040                            tostring, a, method="text")
    3041
    3042          self.assertEquals(
    3043              _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
    3044              tostring(a, encoding="UTF-8", method="text"))
    3045
    3046 -    def test_tounicode(self):
    3047          tounicode = self.etree.tounicode
    3048          Element = self.etree.Element
    3049          SubElement = self.etree.SubElement
    3050
    3051          a = Element('a')
    3052          b = SubElement(a, 'b')
    3053          c = SubElement(a, 'c')
    3054
    3055          self.assert_(isinstance(tounicode(a), _unicode))
    3056          self.assertEquals(_bytes('<a><b></b><c></c></a>'),
    3057                            canonicalize(tounicode(a)))
    3058
    3059 -    def test_tounicode_element(self):
    3060          tounicode = self.etree.tounicode
    3061          Element = self.etree.Element
    3062          SubElement = self.etree.SubElement
    3063
    3064          a = Element('a')
    3065          b = SubElement(a, 'b')
    3066          c = SubElement(a, 'c')
    3067          d = SubElement(c, 'd')
    3068          self.assert_(isinstance(tounicode(b), _unicode))
    3069          self.assert_(isinstance(tounicode(c), _unicode))
    3070          self.assertEquals(_bytes('<b></b>'),
    3071                            canonicalize(tounicode(b)))
    3072          self.assertEquals(_bytes('<c><d></d></c>'),
    3073                            canonicalize(tounicode(c)))
    3074
    3075 -    def test_tounicode_none(self):
    3076          tounicode = self.etree.tounicode
    3077          self.assertRaises(TypeError, self.etree.tounicode, None)
    3078
    3079 -    def test_tounicode_element_tail(self):
    3080          tounicode = self.etree.tounicode
    3081          Element = self.etree.Element
    3082          SubElement = self.etree.SubElement
    3083
    3084          a = Element('a')
    3085          b = SubElement(a, 'b')
    3086          c = SubElement(a, 'c')
    3087          d = SubElement(c, 'd')
    3088          b.tail = 'Foo'
    3089
    3090          self.assert_(isinstance(tounicode(b), _unicode))
    3091          self.assert_(tounicode(b) == '<b/>Foo' or
    3092                       tounicode(b) == '<b />Foo')
    3093
    3094 -    def test_tounicode_pretty(self):
    3095          tounicode = self.etree.tounicode
    3096          Element = self.etree.Element
    3097          SubElement = self.etree.SubElement
    3098
    3099          a = Element('a')
    3100          b = SubElement(a, 'b')
    3101          c = SubElement(a, 'c')
    3102
    3103          result = tounicode(a)
    3104          self.assertEquals(result, "<a><b/><c/></a>")
    3105
    3106          result = tounicode(a, pretty_print=False)
    3107          self.assertEquals(result, "<a><b/><c/></a>")
    3108
    3109          result = tounicode(a, pretty_print=True)
    3110          self.assertEquals(result, "<a>\n  <b/>\n  <c/>\n</a>\n")
    3111
    3112 -    def test_tostring_unicode(self):
    3113          tostring = self.etree.tostring
    3114          Element = self.etree.Element
    3115          SubElement = self.etree.SubElement
    3116
    3117          a = Element('a')
    3118          b = SubElement(a, 'b')
    3119          c = SubElement(a, 'c')
    3120
    3121          self.assert_(isinstance(tostring(a, encoding=_unicode), _unicode))
    3122          self.assertEquals(_bytes('<a><b></b><c></c></a>'),
    3123                            canonicalize(tostring(a, encoding=_unicode)))
    3124
    3125 -    def test_tostring_unicode_element(self):
    3126          tostring = self.etree.tostring
    3127          Element = self.etree.Element
    3128          SubElement = self.etree.SubElement
    3129
    3130          a = Element('a')
    3131          b = SubElement(a, 'b')
    3132          c = SubElement(a, 'c')
    3133          d = SubElement(c, 'd')
    3134          self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode))
    3135          self.assert_(isinstance(tostring(c, encoding=_unicode), _unicode))
    3136          self.assertEquals(_bytes('<b></b>'),
    3137                            canonicalize(tostring(b, encoding=_unicode)))
    3138          self.assertEquals(_bytes('<c><d></d></c>'),
    3139                            canonicalize(tostring(c, encoding=_unicode)))
    3140
    3141 -    def test_tostring_unicode_none(self):
    3142          tostring = self.etree.tostring
    3143          self.assertRaises(TypeError, self.etree.tostring,
    3144                            None, encoding=_unicode)
    3145
    3146 -    def test_tostring_unicode_element_tail(self):
    3147          tostring = self.etree.tostring
    3148          Element = self.etree.Element
    3149          SubElement = self.etree.SubElement
    3150
    3151          a = Element('a')
    3152          b = SubElement(a, 'b')
    3153          c = SubElement(a, 'c')
    3154          d = SubElement(c, 'd')
    3155          b.tail = 'Foo'
    3156
    3157          self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode))
    3158          self.assert_(tostring(b, encoding=_unicode) == '<b/>Foo' or
    3159                       tostring(b, encoding=_unicode) == '<b />Foo')
    3160
    3161 -    def test_tostring_unicode_pretty(self):
    3162          tostring = self.etree.tostring
    3163          Element = self.etree.Element
    3164          SubElement = self.etree.SubElement
    3165
    3166          a = Element('a')
    3167          b = SubElement(a, 'b')
    3168          c = SubElement(a, 'c')
    3169
    3170          result = tostring(a, encoding=_unicode)
    3171          self.assertEquals(result, "<a><b/><c/></a>")
    3172
    3173          result = tostring(a, encoding=_unicode, pretty_print=False)
    3174          self.assertEquals(result, "<a><b/><c/></a>")
    3175
    3176          result = tostring(a, encoding=_unicode, pretty_print=True)
    3177          self.assertEquals(result, "<a>\n  <b/>\n  <c/>\n</a>\n")
    3178
    3179      # helper methods
    3180
    3181 -    def _writeElement(self, element, encoding='us-ascii', compression=0):
    3182          """Write out element for comparison.
    3183          """
    3184          ElementTree = self.etree.ElementTree
    3185          f = BytesIO()
    3186          tree = ElementTree(element=element)
    3187          tree.write(f, encoding=encoding, compression=compression)
    3188          data = f.getvalue()
    3189          if compression:
    3190              data = zlib.decompress(data)
    3191          return canonicalize(data)
    3192
    3193
    3194 -class _XIncludeTestCase(HelperTestCase):
    3195 -    def test_xinclude_text(self):
    3196          filename = fileInTestDir('test_broken.xml')
    3197          root = etree.XML(_bytes('''\
    3198          <doc xmlns:xi="http://www.w3.org/2001/XInclude">
    3199            <xi:include href="%s" parse="text"/>
    3200          </doc>
    3201          ''' % filename))
    3202          old_text = root.text
    3203          content = read_file(filename)
    3204          old_tail = root[0].tail
    3205
    3206          self.include( etree.ElementTree(root) )
    3207          self.assertEquals(old_text + content + old_tail,
    3208                            root.text)
    3209
    3210 -    def test_xinclude(self):
    3211          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'))
    3212          self.assertNotEquals(
    3213              'a',
    3214              tree.getroot()[1].tag)
    3215          # process xincludes
    3216          self.include( tree )
    3217          # check whether we find it replaced with included data
    3218          self.assertEquals(
    3219              'a',
    3220              tree.getroot()[1].tag)
    3221
    3222 -    def test_xinclude_resolver(self):
    3223          class res(etree.Resolver):
    3224              include_text = read_file(fileInTestDir('test.xml'))
    3225              called = {}
    3226              def resolve(self, url, id, context):
    3227                  if url.endswith(".dtd"):
    3228                      self.called["dtd"] = True
    3229                      return self.resolve_filename(
    3230                          fileInTestDir('test.dtd'), context)
    3231                  elif url.endswith("test_xinclude.xml"):
    3232                      self.called["input"] = True
    3233                      return None # delegate to default resolver
    3234                  else:
    3235                      self.called["include"] = True
    3236                      return self.resolve_string(self.include_text, context)
    3237
    3238          res_instance = res()
    3239          parser = etree.XMLParser(load_dtd = True)
    3240          parser.resolvers.add(res_instance)
    3241
    3242          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
    3243                             parser = parser)
    3244
    3245          self.include(tree)
    3246
    3247          called = list(res_instance.called.items())
    3248          called.sort()
    3249          self.assertEquals(
    3250              [("dtd", True), ("include", True), ("input", True)],
    3251              called)
    3252
    3253 -class ETreeXIncludeTestCase(_XIncludeTestCase):
    3254 -    def include(self, tree):
    3255          tree.xinclude()
    3256
    3257
    3258 -class ElementIncludeTestCase(_XIncludeTestCase):
    3259      from lxml import ElementInclude
    3260 -    def include(self, tree):
    3261          self.ElementInclude.include(tree.getroot())
    3262
    3263
    3264 -class ETreeC14NTestCase(HelperTestCase):
    3265 -    def test_c14n(self):
    3266          tree = self.parse(_bytes('<a><b/></a>'))
    3267          f = BytesIO()
    3268          tree.write_c14n(f)
    3269          s = f.getvalue()
    3270          self.assertEquals(_bytes('<a><b></b></a>'),
    3271                            s)
    3272
    3273 -    def test_c14n_gzip(self):
    3274          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3275          f = BytesIO()
    3276          tree.write_c14n(f, compression=9)
    3277          gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
    3278          try:
    3279              s = gzfile.read()
    3280          finally:
    3281              gzfile.close()
    3282          self.assertEquals(_bytes('<a>'+'<b></b>'*200+'</a>'),
    3283                            s)
    3284
    3285 -    def test_c14n_file(self):
    3286          tree = self.parse(_bytes('<a><b/></a>'))
    3287          handle, filename = tempfile.mkstemp()
    3288          try:
    3289              tree.write_c14n(filename)
    3290              data = read_file(filename, 'rb')
    3291          finally:
    3292              os.close(handle)
    3293              os.remove(filename)
    3294          self.assertEquals(_bytes('<a><b></b></a>'),
    3295                            data)
    3296
    3297 -    def test_c14n_file_gzip(self):
    3298          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3299          handle, filename = tempfile.mkstemp()
    3300          try:
    3301              tree.write_c14n(filename, compression=9)
    3302              f = gzip.open(filename, 'rb')
    3303              try:
    3304                  data = f.read()
    3305              finally:
    3306                  f.close()
    3307          finally:
    3308              os.close(handle)
    3309              os.remove(filename)
    3310          self.assertEquals(_bytes('<a>'+'<b></b>'*200+'</a>'),
    3311                            data)
    3312
    3313 -    def test_c14n_with_comments(self):
    3314          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
    3315          f = BytesIO()
    3316          tree.write_c14n(f)
    3317          s = f.getvalue()
    3318          self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
    3319                            s)
    3320          f = BytesIO()
    3321          tree.write_c14n(f, with_comments=True)
    3322          s = f.getvalue()
    3323          self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
    3324                            s)
    3325          f = BytesIO()
    3326          tree.write_c14n(f, with_comments=False)
    3327          s = f.getvalue()
    3328          self.assertEquals(_bytes('<a><b></b></a>'),
    3329                            s)
    3330
    3331 -    def test_c14n_tostring_with_comments(self):
    3332          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
    3333          s = etree.tostring(tree, method='c14n')
    3334          self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
    3335                            s)
    3336          s = etree.tostring(tree, method='c14n', with_comments=True)
    3337          self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
    3338                            s)
    3339          s = etree.tostring(tree, method='c14n', with_comments=False)
    3340          self.assertEquals(_bytes('<a><b></b></a>'),
    3341                            s)
    3342
    3343 -    def test_c14n_element_tostring_with_comments(self):
    3344          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
    3345          s = etree.tostring(tree.getroot(), method='c14n')
    3346          self.assertEquals(_bytes('<a><!--ho--><b></b></a>'),
    3347                            s)
    3348          s = etree.tostring(tree.getroot(), method='c14n', with_comments=True)
    3349          self.assertEquals(_bytes('<a><!--ho--><b></b></a>'),
    3350                            s)
    3351          s = etree.tostring(tree.getroot(), method='c14n', with_comments=False)
    3352          self.assertEquals(_bytes('<a><b></b></a>'),
    3353                            s)
    3354
    3355 -    def test_c14n_exclusive(self):
    3356          tree = self.parse(_bytes(
    3357                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
    3358          f = BytesIO()
    3359          tree.write_c14n(f)
    3360          s = f.getvalue()
    3361          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3362                            s)
    3363          f = BytesIO()
    3364          tree.write_c14n(f, exclusive=False)
    3365          s = f.getvalue()
    3366          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3367                            s)
    3368          f = BytesIO()
    3369          tree.write_c14n(f, exclusive=True)
    3370          s = f.getvalue()
    3371          self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
    3372                            s)
    3373
    3374          f = BytesIO()
    3375          tree.write_c14n(f, exclusive=True, inclusive_ns_prefixes=['z'])
    3376          s = f.getvalue()
    3377          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:z="http://cde"><z:b></z:b></a>'),
    3378                            s)
    3379
    3380 -    def test_c14n_tostring_exclusive(self):
    3381          tree = self.parse(_bytes(
    3382                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
    3383          s = etree.tostring(tree, method='c14n')
    3384          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3385                            s)
    3386          s = etree.tostring(tree, method='c14n', exclusive=False)
    3387          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3388                            s)
    3389          s = etree.tostring(tree, method='c14n', exclusive=True)
    3390          self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
    3391                            s)
    3392
    3393          s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
    3394          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd"><z:b xmlns:z="http://cde"></z:b></a>'),
    3395                            s)
    3396
    3397 -    def test_c14n_element_tostring_exclusive(self):
    3398          tree = self.parse(_bytes(
    3399                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
    3400          s = etree.tostring(tree.getroot(), method='c14n')
    3401          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3402                            s)
    3403          s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
    3404          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3405                            s)
    3406          s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
    3407          self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
    3408                            s)
    3409
    3410          s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
    3411          self.assertEquals(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
    3412                            s)
    3413          s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
    3414          self.assertEquals(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
    3415                            s)
    3416
    3417          s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True, inclusive_ns_prefixes=['y'])
    3418          self.assertEquals(_bytes('<z:b xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
    3419                            s)
    3420
    3421 -    def test_c14n_tostring_inclusive_ns_prefixes(self):
    3422          """ Regression test to fix memory allocation issues (use 3+ inclusive NS spaces)"""
    3423          tree = self.parse(_bytes(
    3424                  '<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
    3425
    3426          s = etree.tostring(tree, method='c14n', exclusive=True, inclusive_ns_prefixes=['x', 'y', 'z'])
    3427          self.assertEquals(_bytes('<a xmlns:x="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3428                            s)
    3429
    3430
    3431 -class ETreeWriteTestCase(HelperTestCase):
    3432 -    def test_write(self):
    3433          tree = self.parse(_bytes('<a><b/></a>'))
    3434          f = BytesIO()
    3435          tree.write(f)
    3436          s = f.getvalue()
    3437          self.assertEquals(_bytes('<a><b/></a>'),
    3438                            s)
    3439
    3440 -    def test_write_gzip(self):
    3441          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3442          f = BytesIO()
    3443          tree.write(f, compression=9)
    3444          gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
    3445          try:
    3446              s = gzfile.read()
    3447          finally:
    3448              gzfile.close()
    3449          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3450                            s)
    3451
    3452 -    def test_write_gzip_level(self):
    3453          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3454          f = BytesIO()
    3455          tree.write(f, compression=0)
    3456          s0 = f.getvalue()
    3457
    3458          f = BytesIO()
    3459          tree.write(f)
    3460          self.assertEquals(f.getvalue(), s0)
    3461
    3462          f = BytesIO()
    3463          tree.write(f, compression=1)
    3464          s = f.getvalue()
    3465          self.assert_(len(s) <= len(s0))
    3466          gzfile = gzip.GzipFile(fileobj=BytesIO(s))
    3467          try:
    3468              s1 = gzfile.read()
    3469          finally:
    3470              gzfile.close()
    3471
    3472          f = BytesIO()
    3473          tree.write(f, compression=9)
    3474          s = f.getvalue()
    3475          self.assert_(len(s) <= len(s0))
    3476          gzfile = gzip.GzipFile(fileobj=BytesIO(s))
    3477          try:
    3478              s9 = gzfile.read()
    3479          finally:
    3480              gzfile.close()
    3481
    3482          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3483                            s0)
    3484          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3485                            s1)
    3486          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3487                            s9)
    3488
    3489 -    def test_write_file(self):
    3490          tree = self.parse(_bytes('<a><b/></a>'))
    3491          handle, filename = tempfile.mkstemp()
    3492          try:
    3493              tree.write(filename)
    3494              data = read_file(filename, 'rb')
    3495          finally:
    3496              os.close(handle)
    3497              os.remove(filename)
    3498          self.assertEquals(_bytes('<a><b/></a>'),
    3499                            data)
    3500
    3501 -    def test_write_file_gzip(self):
    3502          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3503          handle, filename = tempfile.mkstemp()
    3504          try:
    3505              tree.write(filename, compression=9)
    3506              f = gzip.open(filename, 'rb')
    3507              try:
    3508                  data = f.read()
    3509              finally:
    3510                  f.close()
    3511          finally:
    3512              os.close(handle)
    3513              os.remove(filename)
    3514          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3515                            data)
    3516
    3517 -    def test_write_file_gzip_parse(self):
    3518          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3519          handle, filename = tempfile.mkstemp()
    3520          try:
    3521              tree.write(filename, compression=9)
    3522              data = etree.tostring(etree.parse(filename))
    3523          finally:
    3524              os.close(handle)
    3525              os.remove(filename)
    3526          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3527                            data)
    3528
    3529 -    def test_write_file_gzipfile_parse(self):
    3530          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3531          handle, filename = tempfile.mkstemp()
    3532          try:
    3533              tree.write(filename, compression=9)
    3534              data = etree.tostring(etree.parse(
    3535                  gzip.GzipFile(filename)))
    3536          finally:
    3537              os.close(handle)
    3538              os.remove(filename)
    3539          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3540                            data)
    3541
    3542 -class ETreeErrorLogTest(HelperTestCase):
    3543      etree = etree
    3544
    3545 -    def test_parse_error_logging(self):
    3546          parse = self.etree.parse
    3547          f = BytesIO('<a><b></c></b></a>')
    3548          self.etree.clear_error_log()
    3549          try:
    3550              parse(f)
    3551              logs = None
    3552          except SyntaxError:
    3553              e = sys.exc_info()[1]
    3554              logs = e.error_log
    3555          f.close()
    3556          self.assert_([ log for log in logs
    3557                         if 'mismatch' in log.message ])
    3558          self.assert_([ log for log in logs
    3559                         if 'PARSER'   in log.domain_name])
    3560          self.assert_([ log for log in logs
    3561                         if 'ERR_TAG_NAME_MISMATCH' in log.type_name ])
    3562          self.assert_([ log for log in logs
    3563                         if 1 == log.line ])
    3564          self.assert_([ log for log in logs
    3565                         if 15 == log.column ])
    3566
    3567 -    def _test_python_error_logging(self):
    3568          """This can't really be tested as long as there isn't a way to
    3569          reset the logging setup ...
    3570          """
    3571          parse = self.etree.parse
    3572
    3573          messages = []
    3574          class Logger(self.etree.PyErrorLog):
    3575              def log(self, entry, message, *args):
    3576                  messages.append(message)
    3577
    3578          self.etree.use_global_python_log(Logger())
    3579          f = BytesIO('<a><b></c></b></a>')
    3580          try:
    3581              parse(f)
    3582          except SyntaxError:
    3583              pass
    3584          f.close()
    3585
    3586          self.assert_([ message for message in messages
    3587                         if 'mismatch' in message ])
    3588          self.assert_([ message for message in messages
    3589                         if ':PARSER:'   in message])
    3590          self.assert_([ message for message in messages
    3591                         if ':ERR_TAG_NAME_MISMATCH:' in message ])
    3592          self.assert_([ message for message in messages
    3593                         if ':1:15:' in message ])
    3594
    3595 -def test_suite():
    3596      suite = unittest.TestSuite()
    3597      suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)])
    3598      suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)])
    3599      suite.addTests([unittest.makeSuite(ElementIncludeTestCase)])
    3600      suite.addTests([unittest.makeSuite(ETreeC14NTestCase)])
    3601      suite.addTests([unittest.makeSuite(ETreeWriteTestCase)])
    3602      suite.addTests([unittest.makeSuite(ETreeErrorLogTest)])
    3603      suite.addTests(
    3604          [make_doctest('../../../doc/tutorial.txt')])
    3605      suite.addTests(
    3606          [make_doctest('../../../doc/api.txt')])
    3607      suite.addTests(
    3608          [make_doctest('../../../doc/FAQ.txt')])
    3609      suite.addTests(
    3610          [make_doctest('../../../doc/parsing.txt')])
    3611      suite.addTests(
    3612          [make_doctest('../../../doc/resolvers.txt')])
    3613      return suite
    3614
    3615  if __name__ == '__main__':
    3616      print('to test use test.py %s' % __file__)
    3617