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