lxml.tests.test_etree

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

# Source Code for Module lxml.tests.test_etree

       1  # -*- coding: utf-8 -*-
       2
       3  """
       4  Tests specific to the extended etree API
       5
       6  Tests that apply to the general ElementTree API should go into
       7  test_elementtree
       8  """
       9
      10  import os.path
      11  import unittest
      12  import copy
      13  import sys
      14  import re
      15  import operator
      16  import tempfile
      17  import gzip
      18
      19  this_dir = os.path.dirname(__file__)
      20  if this_dir not in sys.path:
      21      sys.path.insert(0, this_dir) # needed for Py3
      22
      23  from common_imports import etree, StringIO, BytesIO, HelperTestCase, fileInTestDir, read_file
      24  from common_imports import SillyFileLike, LargeFileLikeUnicode, doctest, make_doctest
      25  from common_imports import canonicalize, sorted, _str, _bytes
      26
      27  print("")
      28  print("TESTED VERSION: %s" % etree.__version__)
      29  print("    Python:           " + repr(sys.version_info))
      30  print("    lxml.etree:       " + repr(etree.LXML_VERSION))
      31  print("    libxml used:      " + repr(etree.LIBXML_VERSION))
      32  print("    libxml compiled:  " + repr(etree.LIBXML_COMPILED_VERSION))
      33  print("    libxslt used:     " + repr(etree.LIBXSLT_VERSION))
      34  print("    libxslt compiled: " + repr(etree.LIBXSLT_COMPILED_VERSION))
      35  print("")
      36
      37  try:
      38      _unicode = unicode
      39  except NameError:
      40      # Python 3
      41      _unicode = str
      42
      43 -class ETreeOnlyTestCase(HelperTestCase):
      44      """Tests only for etree, not ElementTree"""
      45      etree = etree
      46
      47 -    def test_version(self):
      48          self.assert_(isinstance(etree.__version__, _unicode))
      49          self.assert_(isinstance(etree.LXML_VERSION, tuple))
      50          self.assertEqual(len(etree.LXML_VERSION), 4)
      51          self.assert_(isinstance(etree.LXML_VERSION[0], int))
      52          self.assert_(isinstance(etree.LXML_VERSION[1], int))
      53          self.assert_(isinstance(etree.LXML_VERSION[2], int))
      54          self.assert_(isinstance(etree.LXML_VERSION[3], int))
      55          self.assert_(etree.__version__.startswith(
      56              str(etree.LXML_VERSION[0])))
      57
      58 -    def test_c_api(self):
      59          if hasattr(self.etree, '__pyx_capi__'):
      60              # newer Pyrex compatible C-API
      61              self.assert_(isinstance(self.etree.__pyx_capi__, dict))
      62              self.assert_(len(self.etree.__pyx_capi__) > 0)
      63          else:
      64              # older C-API mechanism
      65              self.assert_(hasattr(self.etree, '_import_c_api'))
      66
      67 -    def test_element_names(self):
      68          Element = self.etree.Element
      69          el = Element('name')
      70          self.assertEquals(el.tag, 'name')
      71          el = Element('{}name')
      72          self.assertEquals(el.tag, 'name')
      73
      74 -    def test_element_name_empty(self):
      75          Element = self.etree.Element
      76          el = Element('name')
      77          self.assertRaises(ValueError, Element, '{}')
      78          self.assertRaises(ValueError, setattr, el, 'tag', '{}')
      79
      80          self.assertRaises(ValueError, Element, '{test}')
      81          self.assertRaises(ValueError, setattr, el, 'tag', '{test}')
      82
      83 -    def test_element_name_colon(self):
      84          Element = self.etree.Element
      85          self.assertRaises(ValueError, Element, 'p:name')
      86          self.assertRaises(ValueError, Element, '{test}p:name')
      87
      88          el = Element('name')
      89          self.assertRaises(ValueError, setattr, el, 'tag', 'p:name')
      90
      91 -    def test_element_name_quote(self):
      92          Element = self.etree.Element
      93          self.assertRaises(ValueError, Element, "p'name")
      94          self.assertRaises(ValueError, Element, 'p"name')
      95
      96          self.assertRaises(ValueError, Element, "{test}p'name")
      97          self.assertRaises(ValueError, Element, '{test}p"name')
      98
      99          el = Element('name')
     100          self.assertRaises(ValueError, setattr, el, 'tag', "p'name")
     101          self.assertRaises(ValueError, setattr, el, 'tag', 'p"name')
     102
     103 -    def test_element_name_space(self):
     104          Element = self.etree.Element
     105          self.assertRaises(ValueError, Element, ' name ')
     106          self.assertRaises(ValueError, Element, 'na me')
     107          self.assertRaises(ValueError, Element, '{test} name')
     108
     109          el = Element('name')
     110          self.assertRaises(ValueError, setattr, el, 'tag', ' name ')
     111
     112 -    def test_subelement_name_empty(self):
     113          Element = self.etree.Element
     114          SubElement = self.etree.SubElement
     115
     116          el = Element('name')
     117          self.assertRaises(ValueError, SubElement, el, '{}')
     118          self.assertRaises(ValueError, SubElement, el, '{test}')
     119
     120 -    def test_subelement_name_colon(self):
     121          Element = self.etree.Element
     122          SubElement = self.etree.SubElement
     123
     124          el = Element('name')
     125          self.assertRaises(ValueError, SubElement, el, 'p:name')
     126          self.assertRaises(ValueError, SubElement, el, '{test}p:name')
     127
     128 -    def test_subelement_name_quote(self):
     129          Element = self.etree.Element
     130          SubElement = self.etree.SubElement
     131
     132          el = Element('name')
     133          self.assertRaises(ValueError, SubElement, el, "p'name")
     134          self.assertRaises(ValueError, SubElement, el, "{test}p'name")
     135
     136          self.assertRaises(ValueError, SubElement, el, 'p"name')
     137          self.assertRaises(ValueError, SubElement, el, '{test}p"name')
     138
     139 -    def test_subelement_name_space(self):
     140          Element = self.etree.Element
     141          SubElement = self.etree.SubElement
     142
     143          el = Element('name')
     144          self.assertRaises(ValueError, SubElement, el, ' name ')
     145          self.assertRaises(ValueError, SubElement, el, 'na me')
     146          self.assertRaises(ValueError, SubElement, el, '{test} name')
     147
     148 -    def test_subelement_attribute_invalid(self):
     149          Element = self.etree.Element
     150          SubElement = self.etree.SubElement
     151
     152          el = Element('name')
     153          self.assertRaises(ValueError, SubElement, el, 'name', {'a b c' : 'abc'})
     154          self.assertRaises(ValueError, SubElement, el, 'name', {'a' : 'a\0\n'})
     155          self.assertEquals(0, len(el))
     156
     157 -    def test_qname_empty(self):
     158          QName = self.etree.QName
     159          self.assertRaises(ValueError, QName, '')
     160          self.assertRaises(ValueError, QName, 'test', '')
     161
     162 -    def test_qname_colon(self):
     163          QName = self.etree.QName
     164          self.assertRaises(ValueError, QName, 'p:name')
     165          self.assertRaises(ValueError, QName, 'test', 'p:name')
     166
     167 -    def test_qname_space(self):
     168          QName = self.etree.QName
     169          self.assertRaises(ValueError, QName, ' name ')
     170          self.assertRaises(ValueError, QName, 'na me')
     171          self.assertRaises(ValueError, QName, 'test', ' name')
     172
     173 -    def test_qname_namespace_localname(self):
     174          # ET doesn't have namespace/localname properties on QNames
     175          QName = self.etree.QName
     176          namespace, localname = 'http://myns', 'a'
     177          qname = QName(namespace, localname)
     178          self.assertEquals(namespace, qname.namespace)
     179          self.assertEquals(localname, qname.localname)
     180
     181 -    def test_qname_element(self):
     182          # ET doesn't have namespace/localname properties on QNames
     183          QName = self.etree.QName
     184          qname1 = QName('http://myns', 'a')
     185          a = self.etree.Element(qname1, nsmap={'p' : 'http://myns'})
     186
     187          qname2 = QName(a)
     188          self.assertEquals(a.tag, qname1.text)
     189          self.assertEquals(qname1.text, qname2.text)
     190          self.assertEquals(qname1, qname2)
     191
     192 -    def test_qname_text_resolve(self):
     193          # ET doesn't resove QNames as text values
     194          etree = self.etree
     195          qname = etree.QName('http://myns', 'a')
     196          a = etree.Element(qname, nsmap={'p' : 'http://myns'})
     197          a.text = qname
     198
     199          self.assertEquals("p:a", a.text)
     200
     201 -    def test_nsmap_prefix_invalid(self):
     202          etree = self.etree
     203          self.assertRaises(ValueError,
     204                            etree.Element, "root", nsmap={'"' : 'testns'})
     205          self.assertRaises(ValueError,
     206                            etree.Element, "root", nsmap={'&' : 'testns'})
     207          self.assertRaises(ValueError,
     208                            etree.Element, "root", nsmap={'a:b' : 'testns'})
     209
     210 -    def test_attribute_has_key(self):
     211          # ET in Py 3.x has no "attrib.has_key()" method
     212          XML = self.etree.XML
     213
     214          root = XML(_bytes('<foo bar="Bar" xmlns:ns="http://ns.codespeak.net/test" ns:baz="Baz" />'))
     215          self.assertEquals(
     216              True, root.attrib.has_key('bar'))
     217          self.assertEquals(
     218              False, root.attrib.has_key('baz'))
     219          self.assertEquals(
     220              False, root.attrib.has_key('hah'))
     221          self.assertEquals(
     222              True,
     223              root.attrib.has_key('{http://ns.codespeak.net/test}baz'))
     224
     225 -    def test_attribute_set(self):
     226          Element = self.etree.Element
     227          root = Element("root")
     228          root.set("attr", "TEST")
     229          self.assertEquals("TEST", root.get("attr"))
     230
     231 -    def test_attribute_set_invalid(self):
     232          # ElementTree accepts arbitrary attribute values
     233          # lxml.etree allows only strings
     234          Element = self.etree.Element
     235          root = Element("root")
     236          self.assertRaises(TypeError, root.set, "newattr", 5)
     237          self.assertRaises(TypeError, root.set, "newattr", None)
     238
     239 -    def test_strip_attributes(self):
     240          XML = self.etree.XML
     241          xml = _bytes('<test a="5" b="10" c="20"><x a="4" b="2"/></test>')
     242
     243          root = XML(xml)
     244          self.etree.strip_attributes(root, 'a')
     245          self.assertEquals(_bytes('<test b="10" c="20"><x b="2"></x></test>'),
     246                            self._writeElement(root))
     247
     248          root = XML(xml)
     249          self.etree.strip_attributes(root, 'b', 'c')
     250          self.assertEquals(_bytes('<test a="5"><x a="4"></x></test>'),
     251                            self._writeElement(root))
     252
     253 -    def test_strip_attributes_ns(self):
     254          XML = self.etree.XML
     255          xml = _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20" n:a="5"><x a="4" n:b="2"/></test>')
     256
     257          root = XML(xml)
     258          self.etree.strip_attributes(root, 'a')
     259          self.assertEquals(
     260              _bytes('<test xmlns:n="http://test/ns" b="10" c="20" n:a="5"><x n:b="2"></x></test>'),
     261              self._writeElement(root))
     262
     263          root = XML(xml)
     264          self.etree.strip_attributes(root, '{http://test/ns}a', 'c')
     265          self.assertEquals(
     266              _bytes('<test xmlns:n="http://test/ns" a="6" b="10"><x a="4" n:b="2"></x></test>'),
     267              self._writeElement(root))
     268
     269          root = XML(xml)
     270          self.etree.strip_attributes(root, '{http://test/ns}*')
     271          self.assertEquals(
     272              _bytes('<test xmlns:n="http://test/ns" a="6" b="10" c="20"><x a="4"></x></test>'),
     273              self._writeElement(root))
     274
     275 -    def test_strip_elements(self):
     276          XML = self.etree.XML
     277          xml = _bytes('<test><a><b><c/></b></a><x><a><b/><c/></a></x></test>')
     278
     279          root = XML(xml)
     280          self.etree.strip_elements(root, 'a')
     281          self.assertEquals(_bytes('<test><x></x></test>'),
     282                            self._writeElement(root))
     283
     284          root = XML(xml)
     285          self.etree.strip_elements(root, 'b', 'c', 'X', 'Y', 'Z')
     286          self.assertEquals(_bytes('<test><a></a><x><a></a></x></test>'),
     287                            self._writeElement(root))
     288
     289          root = XML(xml)
     290          self.etree.strip_elements(root, 'c')
     291          self.assertEquals(_bytes('<test><a><b></b></a><x><a><b></b></a></x></test>'),
     292                            self._writeElement(root))
     293
     294 -    def test_strip_elements_ns(self):
     295          XML = self.etree.XML
     296          xml = _bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"/>C</b>BT</n:a>AT<x>X<a>A<b xmlns="urn:a"/>BT<c xmlns="urn:x"/>CT</a>AT</x>XT</test>')
     297
     298          root = XML(xml)
     299          self.etree.strip_elements(root, 'a')
     300          self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>C</b>BT</n:a>AT<x>X</x>XT</test>'),
     301                            self._writeElement(root))
     302
     303          root = XML(xml)
     304          self.etree.strip_elements(root, '{urn:a}b', 'c')
     305          self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>C</b>BT</n:a>AT<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
     306                            self._writeElement(root))
     307
     308          root = XML(xml)
     309          self.etree.strip_elements(root, '{urn:a}*', 'c')
     310          self.assertEquals(_bytes('<test>TEST<x>X<a>A<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
     311                            self._writeElement(root))
     312
     313          root = XML(xml)
     314          self.etree.strip_elements(root, '{urn:a}*', 'c', with_tail=False)
     315          self.assertEquals(_bytes('<test>TESTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
     316                            self._writeElement(root))
     317
     318 -    def test_strip_tags(self):
     319          XML = self.etree.XML
     320          xml = _bytes('<test>TEST<a>A<b>B<c/>CT</b>BT</a>AT<x>X<a>A<b/>BT<c/>CT</a>AT</x>XT</test>')
     321
     322          root = XML(xml)
     323          self.etree.strip_tags(root, 'a')
     324          self.assertEquals(_bytes('<test>TESTA<b>B<c></c>CT</b>BTAT<x>XA<b></b>BT<c></c>CTAT</x>XT</test>'),
     325                            self._writeElement(root))
     326
     327          root = XML(xml)
     328          self.etree.strip_tags(root, 'b', 'c', 'X', 'Y', 'Z')
     329          self.assertEquals(_bytes('<test>TEST<a>ABCTBT</a>AT<x>X<a>ABTCT</a>AT</x>XT</test>'),
     330                            self._writeElement(root))
     331
     332          root = XML(xml)
     333          self.etree.strip_tags(root, 'c')
     334          self.assertEquals(_bytes('<test>TEST<a>A<b>BCT</b>BT</a>AT<x>X<a>A<b></b>BTCT</a>AT</x>XT</test>'),
     335                            self._writeElement(root))
     336
     337 -    def test_strip_tags_pi_comment(self):
     338          XML = self.etree.XML
     339          PI = self.etree.ProcessingInstruction
     340          Comment = self.etree.Comment
     341          xml = _bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT<?PI2?></test>\n<!--comment3-->\n<?PI1?>')
     342
     343          root = XML(xml)
     344          self.etree.strip_tags(root, PI)
     345          self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT</test>\n<!--comment3-->\n<?PI1?>'),
     346                            self._writeElement(root))
     347
     348          root = XML(xml)
     349          self.etree.strip_tags(root, Comment)
     350          self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT<?PI2?></test>\n<!--comment3-->\n<?PI1?>'),
     351                            self._writeElement(root))
     352
     353          root = XML(xml)
     354          self.etree.strip_tags(root, PI, Comment)
     355          self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT</test>\n<!--comment3-->\n<?PI1?>'),
     356                            self._writeElement(root))
     357
     358          root = XML(xml)
     359          self.etree.strip_tags(root, Comment, PI)
     360          self.assertEquals(_bytes('<!--comment1-->\n<?PI1?>\n<test>TESTXT</test>\n<!--comment3-->\n<?PI1?>'),
     361                            self._writeElement(root))
     362
     363 -    def test_strip_tags_pi_comment_all(self):
     364          XML = self.etree.XML
     365          ElementTree = self.etree.ElementTree
     366          PI = self.etree.ProcessingInstruction
     367          Comment = self.etree.Comment
     368          xml = _bytes('<!--comment1-->\n<?PI1?>\n<test>TEST<!--comment2-->XT<?PI2?></test>\n<!--comment3-->\n<?PI1?>')
     369
     370          root = XML(xml)
     371          self.etree.strip_tags(ElementTree(root), PI)
     372          self.assertEquals(_bytes('<!--comment1-->\n<test>TEST<!--comment2-->XT</test>\n<!--comment3-->'),
     373                            self._writeElement(root))
     374
     375          root = XML(xml)
     376          self.etree.strip_tags(ElementTree(root), Comment)
     377          self.assertEquals(_bytes('<?PI1?>\n<test>TESTXT<?PI2?></test>\n<?PI1?>'),
     378                            self._writeElement(root))
     379
     380          root = XML(xml)
     381          self.etree.strip_tags(ElementTree(root), PI, Comment)
     382          self.assertEquals(_bytes('<test>TESTXT</test>'),
     383                            self._writeElement(root))
     384
     385          root = XML(xml)
     386          self.etree.strip_tags(ElementTree(root), Comment, PI)
     387          self.assertEquals(_bytes('<test>TESTXT</test>'),
     388                            self._writeElement(root))
     389
     390 -    def test_strip_tags_doc_style(self):
     391          XML = self.etree.XML
     392          xml = _bytes('''
     393          <div>
     394              <div>
     395                  I like <strong>sheep</strong>.
     396                  <br/>
     397                  I like lots of <strong>sheep</strong>.
     398                  <br/>
     399                  Click <a href="http://www.sheep.com">here</a> for <a href="http://www.sheep.com">those</a> sheep.
     400                  <br/>
     401              </div>
     402          </div>
     403          '''.strip())
     404
     405          root = XML(xml)
     406          self.etree.strip_tags(root, 'a')
     407          self.assertEquals(re.sub(_bytes('</?a[^>]*>'), _bytes(''), xml).replace(_bytes('<br/>'), _bytes('<br></br>')),
     408                            self._writeElement(root))
     409
     410          root = XML(xml)
     411          self.etree.strip_tags(root, 'a', 'br')
     412          self.assertEquals(re.sub(_bytes('</?a[^>]*>'), _bytes(''),
     413                                   re.sub(_bytes('<br[^>]*>'), _bytes(''), xml)),
     414                            self._writeElement(root))
     415
     416 -    def test_strip_tags_ns(self):
     417          XML = self.etree.XML
     418          xml = _bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"/>CT</b>BT</n:a>AT<x>X<a>A<b xmlns="urn:a"/>BT<c xmlns="urn:x"/>CT</a>AT</x>XT</test>')
     419
     420          root = XML(xml)
     421          self.etree.strip_tags(root, 'a')
     422          self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>CT</b>BT</n:a>AT<x>XA<b xmlns="urn:a"></b>BT<c xmlns="urn:x"></c>CTAT</x>XT</test>'),
     423                            self._writeElement(root))
     424
     425          root = XML(xml)
     426          self.etree.strip_tags(root, '{urn:a}b', 'c')
     427          self.assertEquals(_bytes('<test>TEST<n:a xmlns:n="urn:a">A<b>B<c xmlns="urn:c"></c>CT</b>BT</n:a>AT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
     428                            self._writeElement(root))
     429
     430          root = XML(xml)
     431          self.etree.strip_tags(root, '{urn:a}*', 'c')
     432          self.assertEquals(_bytes('<test>TESTA<b>B<c xmlns="urn:c"></c>CT</b>BTAT<x>X<a>ABT<c xmlns="urn:x"></c>CT</a>AT</x>XT</test>'),
     433                            self._writeElement(root))
     434
     435 -    def test_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_error(self):
    1314          Element = self.etree.Element
    1315          root = Element('root')
    1316          # raises AssertionError in ElementTree
    1317          self.assertRaises(TypeError, root.append, None)
    1318          self.assertRaises(TypeError, root.extend, [None])
    1319          self.assertRaises(TypeError, root.extend, [Element('one'), None])
    1320          self.assertEquals('one', root[0].tag)
    1321
    1322 -    def test_addnext(self):
    1323          Element = self.etree.Element
    1324          SubElement = self.etree.SubElement
    1325          root = Element('root')
    1326          SubElement(root, 'a')
    1327          SubElement(root, 'b')
    1328
    1329          self.assertEquals(['a', 'b'],
    1330                            [c.tag for c in root])
    1331          root[1].addnext(root[0])
    1332          self.assertEquals(['b', 'a'],
    1333                            [c.tag for c in root])
    1334
    1335 -    def test_addprevious(self):
    1336          Element = self.etree.Element
    1337          SubElement = self.etree.SubElement
    1338          root = Element('root')
    1339          SubElement(root, 'a')
    1340          SubElement(root, 'b')
    1341
    1342          self.assertEquals(['a', 'b'],
    1343                            [c.tag for c in root])
    1344          root[0].addprevious(root[1])
    1345          self.assertEquals(['b', 'a'],
    1346                            [c.tag for c in root])
    1347
    1348 -    def test_addnext_root(self):
    1349          Element = self.etree.Element
    1350          a = Element('a')
    1351          b = Element('b')
    1352          self.assertRaises(TypeError, a.addnext, b)
    1353
    1354 -    def test_addnext_root(self):
    1355          Element = self.etree.Element
    1356          a = Element('a')
    1357          b = Element('b')
    1358          self.assertRaises(TypeError, a.addnext, b)
    1359
    1360 -    def test_addprevious_pi(self):
    1361          Element = self.etree.Element
    1362          SubElement = self.etree.SubElement
    1363          PI = self.etree.PI
    1364          root = Element('root')
    1365          SubElement(root, 'a')
    1366          pi = PI('TARGET', 'TEXT')
    1367          pi.tail = "TAIL"
    1368
    1369          self.assertEquals(_bytes('<root><a></a></root>'),
    1370                            self._writeElement(root))
    1371          root[0].addprevious(pi)
    1372          self.assertEquals(_bytes('<root><?TARGET TEXT?>TAIL<a></a></root>'),
    1373                            self._writeElement(root))
    1374
    1375 -    def test_addprevious_root_pi(self):
    1376          Element = self.etree.Element
    1377          PI = self.etree.PI
    1378          root = Element('root')
    1379          pi = PI('TARGET', 'TEXT')
    1380          pi.tail = "TAIL"
    1381
    1382          self.assertEquals(_bytes('<root></root>'),
    1383                            self._writeElement(root))
    1384          root.addprevious(pi)
    1385          self.assertEquals(_bytes('<?TARGET TEXT?>\n<root></root>'),
    1386                            self._writeElement(root))
    1387
    1388 -    def test_addnext_pi(self):
    1389          Element = self.etree.Element
    1390          SubElement = self.etree.SubElement
    1391          PI = self.etree.PI
    1392          root = Element('root')
    1393          SubElement(root, 'a')
    1394          pi = PI('TARGET', 'TEXT')
    1395          pi.tail = "TAIL"
    1396
    1397          self.assertEquals(_bytes('<root><a></a></root>'),
    1398                            self._writeElement(root))
    1399          root[0].addnext(pi)
    1400          self.assertEquals(_bytes('<root><a></a><?TARGET TEXT?>TAIL</root>'),
    1401                            self._writeElement(root))
    1402
    1403 -    def test_addnext_root_pi(self):
    1404          Element = self.etree.Element
    1405          PI = self.etree.PI
    1406          root = Element('root')
    1407          pi = PI('TARGET', 'TEXT')
    1408          pi.tail = "TAIL"
    1409
    1410          self.assertEquals(_bytes('<root></root>'),
    1411                            self._writeElement(root))
    1412          root.addnext(pi)
    1413          self.assertEquals(_bytes('<root></root>\n<?TARGET TEXT?>'),
    1414                            self._writeElement(root))
    1415
    1416 -    def test_addnext_comment(self):
    1417          Element = self.etree.Element
    1418          SubElement = self.etree.SubElement
    1419          Comment = self.etree.Comment
    1420          root = Element('root')
    1421          SubElement(root, 'a')
    1422          comment = Comment('TEXT ')
    1423          comment.tail = "TAIL"
    1424
    1425          self.assertEquals(_bytes('<root><a></a></root>'),
    1426                            self._writeElement(root))
    1427          root[0].addnext(comment)
    1428          self.assertEquals(_bytes('<root><a></a><!--TEXT -->TAIL</root>'),
    1429                            self._writeElement(root))
    1430
    1431 -    def test_addnext_root_comment(self):
    1432          Element = self.etree.Element
    1433          Comment = self.etree.Comment
    1434          root = Element('root')
    1435          comment = Comment('TEXT ')
    1436          comment.tail = "TAIL"
    1437
    1438          self.assertEquals(_bytes('<root></root>'),
    1439                            self._writeElement(root))
    1440          root.addnext(comment)
    1441          self.assertEquals(_bytes('<root></root>\n<!--TEXT -->'),
    1442                            self._writeElement(root))
    1443
    1444 -    def test_addprevious_comment(self):
    1445          Element = self.etree.Element
    1446          SubElement = self.etree.SubElement
    1447          Comment = self.etree.Comment
    1448          root = Element('root')
    1449          SubElement(root, 'a')
    1450          comment = Comment('TEXT ')
    1451          comment.tail = "TAIL"
    1452
    1453          self.assertEquals(_bytes('<root><a></a></root>'),
    1454                            self._writeElement(root))
    1455          root[0].addprevious(comment)
    1456          self.assertEquals(_bytes('<root><!--TEXT -->TAIL<a></a></root>'),
    1457                            self._writeElement(root))
    1458
    1459 -    def test_addprevious_root_comment(self):
    1460          Element = self.etree.Element
    1461          Comment = self.etree.Comment
    1462          root = Element('root')
    1463          comment = Comment('TEXT ')
    1464          comment.tail = "TAIL"
    1465
    1466          self.assertEquals(_bytes('<root></root>'),
    1467                            self._writeElement(root))
    1468          root.addprevious(comment)
    1469          self.assertEquals(_bytes('<!--TEXT -->\n<root></root>'),
    1470                            self._writeElement(root))
    1471
    1472      # ET's Elements have items() and key(), but not values()
    1473 -    def test_attribute_values(self):
    1474          XML = self.etree.XML
    1475
    1476          root = XML(_bytes('<doc alpha="Alpha" beta="Beta" gamma="Gamma"/>'))
    1477          values = root.values()
    1478          values.sort()
    1479          self.assertEquals(['Alpha', 'Beta', 'Gamma'], values)
    1480
    1481      # gives error in ElementTree
    1482 -    def test_comment_empty(self):
    1483          Element = self.etree.Element
    1484          Comment = self.etree.Comment
    1485
    1486          a = Element('a')
    1487          a.append(Comment())
    1488          self.assertEquals(
    1489              _bytes('<a><!----></a>'),
    1490              self._writeElement(a))
    1491
    1492      # ElementTree ignores comments
    1493 -    def test_comment_parse_empty(self):
    1494          ElementTree = self.etree.ElementTree
    1495          tostring = self.etree.tostring
    1496
    1497          xml = _bytes('<a><b/><!----><c/></a>')
    1498          f = BytesIO(xml)
    1499          doc = ElementTree(file=f)
    1500          a = doc.getroot()
    1501          self.assertEquals(
    1502              '',
    1503              a[1].text)
    1504          self.assertEquals(
    1505              xml,
    1506              tostring(a))
    1507
    1508      # ElementTree ignores comments
    1509 -    def test_comment_no_proxy_yet(self):
    1510          ElementTree = self.etree.ElementTree
    1511
    1512          f = BytesIO('<a><b></b><!-- hoi --><c></c></a>')
    1513          doc = ElementTree(file=f)
    1514          a = doc.getroot()
    1515          self.assertEquals(
    1516              ' hoi ',
    1517              a[1].text)
    1518
    1519      # does not raise an exception in ElementTree
    1520 -    def test_comment_immutable(self):
    1521          Element = self.etree.Element
    1522          Comment = self.etree.Comment
    1523
    1524          c = Comment()
    1525          el = Element('myel')
    1526
    1527          self.assertRaises(TypeError, c.append, el)
    1528          self.assertRaises(TypeError, c.insert, 0, el)
    1529          self.assertRaises(TypeError, c.set, "myattr", "test")
    1530
    1531      # test passing 'None' to dump
    1532 -    def test_dump_none(self):
    1533          self.assertRaises(TypeError, self.etree.dump, None)
    1534
    1535 -    def test_prefix(self):
    1536          ElementTree = self.etree.ElementTree
    1537
    1538          f = BytesIO('<a xmlns:foo="http://www.infrae.com/ns/1"><foo:b/></a>')
    1539          doc = ElementTree(file=f)
    1540          a = doc.getroot()
    1541          self.assertEquals(
    1542              None,
    1543              a.prefix)
    1544          self.assertEquals(
    1545              'foo',
    1546              a[0].prefix)
    1547
    1548 -    def test_prefix_default_ns(self):
    1549          ElementTree = self.etree.ElementTree
    1550
    1551          f = BytesIO('<a xmlns="http://www.infrae.com/ns/1"><b/></a>')
    1552          doc = ElementTree(file=f)
    1553          a = doc.getroot()
    1554          self.assertEquals(
    1555              None,
    1556              a.prefix)
    1557          self.assertEquals(
    1558              None,
    1559              a[0].prefix)
    1560
    1561 -    def test_getparent(self):
    1562          Element = self.etree.Element
    1563          SubElement = self.etree.SubElement
    1564
    1565          a = Element('a')
    1566          b = SubElement(a, 'b')
    1567          c = SubElement(a, 'c')
    1568          d = SubElement(b, 'd')
    1569          self.assertEquals(
    1570              None,
    1571              a.getparent())
    1572          self.assertEquals(
    1573              a,
    1574              b.getparent())
    1575          self.assertEquals(
    1576              b.getparent(),
    1577              c.getparent())
    1578          self.assertEquals(
    1579              b,
    1580              d.getparent())
    1581
    1582 -    def test_iterchildren(self):
    1583          XML = self.etree.XML
    1584
    1585          root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
    1586          result = []
    1587          for el in root.iterchildren():
    1588              result.append(el.tag)
    1589          self.assertEquals(['one', 'two', 'three'], result)
    1590
    1591 -    def test_iterchildren_reversed(self):
    1592          XML = self.etree.XML
    1593
    1594          root = XML(_bytes('<doc><one/><two>Two</two>Hm<three/></doc>'))
    1595          result = []
    1596          for el in root.iterchildren(reversed=True):
    1597              result.append(el.tag)
    1598          self.assertEquals(['three', 'two', 'one'], result)
    1599
    1600 -    def test_iterchildren_tag(self):
    1601          XML = self.etree.XML
    1602
    1603          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
    1604          result = []
    1605          for el in root.iterchildren(tag='two'):
    1606              result.append(el.text)
    1607          self.assertEquals(['Two', 'Bla'], result)
    1608
    1609 -    def test_iterchildren_tag_reversed(self):
    1610          XML = self.etree.XML
    1611
    1612          root = XML(_bytes('<doc><one/><two>Two</two>Hm<two>Bla</two></doc>'))
    1613          result = []
    1614          for el in root.iterchildren(reversed=True, tag='two'):
    1615              result.append(el.text)
    1616          self.assertEquals(['Bla', 'Two'], result)
    1617
    1618 -    def test_iterancestors(self):
    1619          Element    = self.etree.Element
    1620          SubElement = self.etree.SubElement
    1621
    1622          a = Element('a')
    1623          b = SubElement(a, 'b')
    1624          c = SubElement(a, 'c')
    1625          d = SubElement(b, 'd')
    1626          self.assertEquals(
    1627              [],
    1628              list(a.iterancestors()))
    1629          self.assertEquals(
    1630              [a],
    1631              list(b.iterancestors()))
    1632          self.assertEquals(
    1633              [a],
    1634              list(c.iterancestors()))
    1635          self.assertEquals(
    1636              [b, a],
    1637              list(d.iterancestors()))
    1638
    1639 -    def test_iterancestors_tag(self):
    1640          Element    = self.etree.Element
    1641          SubElement = self.etree.SubElement
    1642
    1643          a = Element('a')
    1644          b = SubElement(a, 'b')
    1645          c = SubElement(a, 'c')
    1646          d = SubElement(b, 'd')
    1647          self.assertEquals(
    1648              [a],
    1649              list(d.iterancestors(tag='a')))
    1650
    1651 -    def test_iterdescendants(self):
    1652          Element = self.etree.Element
    1653          SubElement = self.etree.SubElement
    1654
    1655          a = Element('a')
    1656          b = SubElement(a, 'b')
    1657          c = SubElement(a, 'c')
    1658          d = SubElement(b, 'd')
    1659          e = SubElement(c, 'e')
    1660
    1661          self.assertEquals(
    1662              [b, d, c, e],
    1663              list(a.iterdescendants()))
    1664          self.assertEquals(
    1665              [],
    1666              list(d.iterdescendants()))
    1667
    1668 -    def test_iterdescendants_tag(self):
    1669          Element = self.etree.Element
    1670          SubElement = self.etree.SubElement
    1671
    1672          a = Element('a')
    1673          b = SubElement(a, 'b')
    1674          c = SubElement(a, 'c')
    1675          d = SubElement(b, 'd')
    1676          e = SubElement(c, 'e')
    1677
    1678          self.assertEquals(
    1679              [],
    1680              list(a.iterdescendants('a')))
    1681          a2 = SubElement(e, 'a')
    1682          self.assertEquals(
    1683              [a2],
    1684              list(a.iterdescendants('a')))
    1685          self.assertEquals(
    1686              [a2],
    1687              list(c.iterdescendants('a')))
    1688
    1689 -    def test_getroottree(self):
    1690          Element = self.etree.Element
    1691          SubElement = self.etree.SubElement
    1692
    1693          a = Element('a')
    1694          b = SubElement(a, 'b')
    1695          c = SubElement(a, 'c')
    1696          d = SubElement(b, 'd')
    1697          self.assertEquals(
    1698              a,
    1699              a.getroottree().getroot())
    1700          self.assertEquals(
    1701              a,
    1702              b.getroottree().getroot())
    1703          self.assertEquals(
    1704              a,
    1705              d.getroottree().getroot())
    1706
    1707 -    def test_getnext(self):
    1708          Element    = self.etree.Element
    1709          SubElement = self.etree.SubElement
    1710
    1711          a = Element('a')
    1712          b = SubElement(a, 'b')
    1713          c = SubElement(a, 'c')
    1714          self.assertEquals(
    1715              None,
    1716              a.getnext())
    1717          self.assertEquals(
    1718              c,
    1719              b.getnext())
    1720          self.assertEquals(
    1721              None,
    1722              c.getnext())
    1723
    1724 -    def test_getprevious(self):
    1725          Element    = self.etree.Element
    1726          SubElement = self.etree.SubElement
    1727
    1728          a = Element('a')
    1729          b = SubElement(a, 'b')
    1730          c = SubElement(a, 'c')
    1731          d = SubElement(b, 'd')
    1732          self.assertEquals(
    1733              None,
    1734              a.getprevious())
    1735          self.assertEquals(
    1736              b,
    1737              c.getprevious())
    1738          self.assertEquals(
    1739              None,
    1740              b.getprevious())
    1741
    1742 -    def test_itersiblings(self):
    1743          Element    = self.etree.Element
    1744          SubElement = self.etree.SubElement
    1745
    1746          a = Element('a')
    1747          b = SubElement(a, 'b')
    1748          c = SubElement(a, 'c')
    1749          d = SubElement(b, 'd')
    1750          self.assertEquals(
    1751              [],
    1752              list(a.itersiblings()))
    1753          self.assertEquals(
    1754              [c],
    1755              list(b.itersiblings()))
    1756          self.assertEquals(
    1757              [],
    1758              list(c.itersiblings()))
    1759          self.assertEquals(
    1760              [b],
    1761              list(c.itersiblings(preceding=True)))
    1762          self.assertEquals(
    1763              [],
    1764              list(b.itersiblings(preceding=True)))
    1765
    1766 -    def test_itersiblings_tag(self):
    1767          Element    = self.etree.Element
    1768          SubElement = self.etree.SubElement
    1769
    1770          a = Element('a')
    1771          b = SubElement(a, 'b')
    1772          c = SubElement(a, 'c')
    1773          d = SubElement(b, 'd')
    1774          self.assertEquals(
    1775              [],
    1776              list(a.itersiblings(tag='XXX')))
    1777          self.assertEquals(
    1778              [c],
    1779              list(b.itersiblings(tag='c')))
    1780          self.assertEquals(
    1781              [b],
    1782              list(c.itersiblings(preceding=True, tag='b')))
    1783          self.assertEquals(
    1784              [],
    1785              list(c.itersiblings(preceding=True, tag='c')))
    1786
    1787 -    def test_parseid(self):
    1788          parseid = self.etree.parseid
    1789          XML     = self.etree.XML
    1790          xml_text = _bytes('''
    1791          <!DOCTYPE document [
    1792          <!ELEMENT document (h1,p)*>
    1793          <!ELEMENT h1 (#PCDATA)>
    1794          <!ATTLIST h1 myid ID #REQUIRED>
    1795          <!ELEMENT p  (#PCDATA)>
    1796          <!ATTLIST p  someid ID #REQUIRED>
    1797          ]>
    1798          <document>
    1799            <h1 myid="chapter1">...</h1>
    1800            <p id="note1" class="note">...</p>
    1801            <p>Regular paragraph.</p>
    1802            <p xml:id="xmlid">XML:ID paragraph.</p>
    1803            <p someid="warn1" class="warning">...</p>
    1804          </document>
    1805          ''')
    1806
    1807          tree, dic = parseid(BytesIO(xml_text))
    1808          root = tree.getroot()
    1809          root2 = XML(xml_text)
    1810          self.assertEquals(self._writeElement(root),
    1811                            self._writeElement(root2))
    1812          expected = {
    1813              "chapter1" : root[0],
    1814              "xmlid"    : root[3],
    1815              "warn1"    : root[4]
    1816              }
    1817          self.assert_("chapter1" in dic)
    1818          self.assert_("warn1" in dic)
    1819          self.assert_("xmlid" in dic)
    1820          self._checkIDDict(dic, expected)
    1821
    1822 -    def test_XMLDTDID(self):
    1823          XMLDTDID = self.etree.XMLDTDID
    1824          XML      = self.etree.XML
    1825          xml_text = _bytes('''
    1826          <!DOCTYPE document [
    1827          <!ELEMENT document (h1,p)*>
    1828          <!ELEMENT h1 (#PCDATA)>
    1829          <!ATTLIST h1 myid ID #REQUIRED>
    1830          <!ELEMENT p  (#PCDATA)>
    1831          <!ATTLIST p  someid ID #REQUIRED>
    1832          ]>
    1833          <document>
    1834            <h1 myid="chapter1">...</h1>
    1835            <p id="note1" class="note">...</p>
    1836            <p>Regular paragraph.</p>
    1837            <p xml:id="xmlid">XML:ID paragraph.</p>
    1838            <p someid="warn1" class="warning">...</p>
    1839          </document>
    1840          ''')
    1841
    1842          root, dic = XMLDTDID(xml_text)
    1843          root2 = XML(xml_text)
    1844          self.assertEquals(self._writeElement(root),
    1845                            self._writeElement(root2))
    1846          expected = {
    1847              "chapter1" : root[0],
    1848              "xmlid"    : root[3],
    1849              "warn1"    : root[4]
    1850              }
    1851          self.assert_("chapter1" in dic)
    1852          self.assert_("warn1" in dic)
    1853          self.assert_("xmlid" in dic)
    1854          self._checkIDDict(dic, expected)
    1855
    1856 -    def test_XMLDTDID_empty(self):
    1857          XMLDTDID = self.etree.XMLDTDID
    1858          XML      = self.etree.XML
    1859          xml_text = _bytes('''
    1860          <document>
    1861            <h1 myid="chapter1">...</h1>
    1862            <p id="note1" class="note">...</p>
    1863            <p>Regular paragraph.</p>
    1864            <p someid="warn1" class="warning">...</p>
    1865          </document>
    1866          ''')
    1867
    1868          root, dic = XMLDTDID(xml_text)
    1869          root2 = XML(xml_text)
    1870          self.assertEquals(self._writeElement(root),
    1871                            self._writeElement(root2))
    1872          expected = {}
    1873          self._checkIDDict(dic, expected)
    1874
    1875 -    def _checkIDDict(self, dic, expected):
    1876          self.assertEquals(len(dic),
    1877                            len(expected))
    1878          self.assertEquals(sorted(dic.items()),
    1879                            sorted(expected.items()))
    1880          if sys.version_info < (3,):
    1881              self.assertEquals(sorted(dic.iteritems()),
    1882                                sorted(expected.iteritems()))
    1883          self.assertEquals(sorted(dic.keys()),
    1884                            sorted(expected.keys()))
    1885          if sys.version_info < (3,):
    1886              self.assertEquals(sorted(dic.iterkeys()),
    1887                                sorted(expected.iterkeys()))
    1888          if sys.version_info < (3,):
    1889              self.assertEquals(sorted(dic.values()),
    1890                                sorted(expected.values()))
    1891              self.assertEquals(sorted(dic.itervalues()),
    1892                                sorted(expected.itervalues()))
    1893
    1894 -    def test_namespaces(self):
    1895          etree = self.etree
    1896
    1897          r = {'foo': 'http://ns.infrae.com/foo'}
    1898          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    1899          self.assertEquals(
    1900              'foo',
    1901              e.prefix)
    1902          self.assertEquals(
    1903              _bytes('<foo:bar xmlns:foo="http://ns.infrae.com/foo"></foo:bar>'),
    1904              self._writeElement(e))
    1905
    1906 -    def test_namespaces_default(self):
    1907          etree = self.etree
    1908
    1909          r = {None: 'http://ns.infrae.com/foo'}
    1910          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    1911          self.assertEquals(
    1912              None,
    1913              e.prefix)
    1914          self.assertEquals(
    1915              '{http://ns.infrae.com/foo}bar',
    1916              e.tag)
    1917          self.assertEquals(
    1918              _bytes('<bar xmlns="http://ns.infrae.com/foo"></bar>'),
    1919              self._writeElement(e))
    1920
    1921 -    def test_namespaces_default_and_attr(self):
    1922          etree = self.etree
    1923
    1924          r = {None: 'http://ns.infrae.com/foo',
    1925               'hoi': 'http://ns.infrae.com/hoi'}
    1926          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    1927          e.set('{http://ns.infrae.com/hoi}test', 'value')
    1928          self.assertEquals(
    1929              _bytes('<bar xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi" hoi:test="value"></bar>'),
    1930              self._writeElement(e))
    1931
    1932 -    def test_namespaces_elementtree(self):
    1933          etree = self.etree
    1934          r = {None: 'http://ns.infrae.com/foo',
    1935               'hoi': 'http://ns.infrae.com/hoi'}
    1936          e = etree.Element('{http://ns.infrae.com/foo}z', nsmap=r)
    1937          tree = etree.ElementTree(element=e)
    1938          etree.SubElement(e, '{http://ns.infrae.com/hoi}x')
    1939          self.assertEquals(
    1940              _bytes('<z xmlns="http://ns.infrae.com/foo" xmlns:hoi="http://ns.infrae.com/hoi"><hoi:x></hoi:x></z>'),
    1941              self._writeElement(e))
    1942
    1943 -    def test_namespaces_default_copy_element(self):
    1944          etree = self.etree
    1945
    1946          r = {None: 'http://ns.infrae.com/foo'}
    1947          e1 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    1948          e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    1949
    1950          e1.append(e2)
    1951
    1952          self.assertEquals(
    1953              None,
    1954              e1.prefix)
    1955          self.assertEquals(
    1956              None,
    1957              e1[0].prefix)
    1958          self.assertEquals(
    1959              '{http://ns.infrae.com/foo}bar',
    1960              e1.tag)
    1961          self.assertEquals(
    1962              '{http://ns.infrae.com/foo}bar',
    1963              e1[0].tag)
    1964
    1965 -    def test_namespaces_copy_element(self):
    1966          etree = self.etree
    1967
    1968          r = {None: 'http://ns.infrae.com/BAR'}
    1969          e1 = etree.Element('{http://ns.infrae.com/BAR}bar', nsmap=r)
    1970          e2 = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    1971
    1972          e1.append(e2)
    1973
    1974          self.assertEquals(
    1975              None,
    1976              e1.prefix)
    1977          self.assertNotEquals(
    1978              None,
    1979              e2.prefix)
    1980          self.assertEquals(
    1981              '{http://ns.infrae.com/BAR}bar',
    1982              e1.tag)
    1983          self.assertEquals(
    1984              '{http://ns.infrae.com/foo}bar',
    1985              e2.tag)
    1986
    1987 -    def test_namespaces_reuse_after_move(self):
    1988          ns_href = "http://a.b.c"
    1989          one = self.etree.fromstring(
    1990              _bytes('<foo><bar xmlns:ns="%s"><ns:baz/></bar></foo>' % ns_href))
    1991          baz = one[0][0]
    1992
    1993          two = self.etree.fromstring(
    1994              _bytes('<root xmlns:ns="%s"/>' % ns_href))
    1995          two.append(baz)
    1996          del one # make sure the source document is deallocated
    1997
    1998          self.assertEquals('{%s}baz' % ns_href, baz.tag)
    1999          self.assertEquals(
    2000              _bytes('<root xmlns:ns="%s"><ns:baz/></root>' % ns_href),
    2001              self.etree.tostring(two))
    2002
    2003 -    def test_namespace_cleanup(self):
    2004          xml = _bytes('<foo xmlns="F" xmlns:x="x"><bar xmlns:ns="NS" xmlns:b="b" xmlns="B"><ns:baz/></bar></foo>')
    2005          root = self.etree.fromstring(xml)
    2006          self.assertEquals(xml,
    2007                            self.etree.tostring(root))
    2008          self.etree.cleanup_namespaces(root)
    2009          self.assertEquals(
    2010              _bytes('<foo xmlns="F"><bar xmlns:ns="NS" xmlns="B"><ns:baz/></bar></foo>'),
    2011              self.etree.tostring(root))
    2012
    2013 -    def test_element_nsmap(self):
    2014          etree = self.etree
    2015
    2016          r = {None: 'http://ns.infrae.com/foo',
    2017               'hoi': 'http://ns.infrae.com/hoi'}
    2018          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=r)
    2019          self.assertEquals(
    2020              r,
    2021              e.nsmap)
    2022
    2023 -    def test_subelement_nsmap(self):
    2024          etree = self.etree
    2025
    2026          re = {None: 'http://ns.infrae.com/foo',
    2027               'hoi': 'http://ns.infrae.com/hoi'}
    2028          e = etree.Element('{http://ns.infrae.com/foo}bar', nsmap=re)
    2029
    2030          rs = {None: 'http://ns.infrae.com/honk',
    2031               'top': 'http://ns.infrae.com/top'}
    2032          s = etree.SubElement(e, '{http://ns.infrae.com/honk}bar', nsmap=rs)
    2033
    2034          r = re.copy()
    2035          r.update(rs)
    2036          self.assertEquals(re, e.nsmap)
    2037          self.assertEquals(r,  s.nsmap)
    2038
    2039 -    def test_getiterator_filter_namespace(self):
    2040          Element = self.etree.Element
    2041          SubElement = self.etree.SubElement
    2042
    2043          a = Element('{a}a')
    2044          b = SubElement(a, '{a}b')
    2045          c = SubElement(a, '{a}c')
    2046          d = SubElement(b, '{b}d')
    2047          e = SubElement(c, '{a}e')
    2048          f = SubElement(c, '{b}f')
    2049
    2050          self.assertEquals(
    2051              [a],
    2052              list(a.getiterator('{a}a')))
    2053          self.assertEquals(
    2054              [],
    2055              list(a.getiterator('{b}a')))
    2056          self.assertEquals(
    2057              [],
    2058              list(a.getiterator('a')))
    2059          self.assertEquals(
    2060              [f],
    2061              list(c.getiterator('{b}*')))
    2062          self.assertEquals(
    2063              [d, f],
    2064              list(a.getiterator('{b}*')))
    2065
    2066 -    def test_getiterator_filter_entities(self):
    2067          Element = self.etree.Element
    2068          Entity = self.etree.Entity
    2069          SubElement = self.etree.SubElement
    2070
    2071          a = Element('a')
    2072          b = SubElement(a, 'b')
    2073          entity_b = Entity("TEST-b")
    2074          b.append(entity_b)
    2075
    2076          self.assertEquals(
    2077              [entity_b],
    2078              list(a.getiterator(Entity)))
    2079
    2080          entity_a = Entity("TEST-a")
    2081          a.append(entity_a)
    2082
    2083          self.assertEquals(
    2084              [entity_b, entity_a],
    2085              list(a.getiterator(Entity)))
    2086
    2087          self.assertEquals(
    2088              [entity_b],
    2089              list(b.getiterator(Entity)))
    2090
    2091 -    def test_getiterator_filter_element(self):
    2092          Element = self.etree.Element
    2093          Comment = self.etree.Comment
    2094          PI = self.etree.PI
    2095          SubElement = self.etree.SubElement
    2096
    2097          a = Element('a')
    2098          b = SubElement(a, 'b')
    2099          a.append(Comment("test"))
    2100          a.append(PI("pi", "content"))
    2101          c = SubElement(a, 'c')
    2102
    2103          self.assertEquals(
    2104              [a, b, c],
    2105              list(a.getiterator(Element)))
    2106
    2107 -    def test_getiterator_filter_all_comment_pi(self):
    2108          # ElementTree iterates over everything here
    2109          Element = self.etree.Element
    2110          Comment = self.etree.Comment
    2111          PI = self.etree.PI
    2112          SubElement = self.etree.SubElement
    2113
    2114          a = Element('a')
    2115          b = SubElement(a, 'b')
    2116          a.append(Comment("test"))
    2117          a.append(PI("pi", "content"))
    2118          c = SubElement(a, 'c')
    2119
    2120          self.assertEquals(
    2121              [a, b, c],
    2122              list(a.getiterator('*')))
    2123
    2124 -    def test_elementtree_find_qname(self):
    2125          XML = self.etree.XML
    2126          ElementTree = self.etree.ElementTree
    2127          QName = self.etree.QName
    2128          tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
    2129          self.assertEquals(tree.find(QName("c")), tree.getroot()[2])
    2130
    2131 -    def test_elementtree_findall_qname(self):
    2132          XML = self.etree.XML
    2133          ElementTree = self.etree.ElementTree
    2134          QName = self.etree.QName
    2135          tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
    2136          self.assertEquals(len(list(tree.findall(QName("c")))), 1)
    2137
    2138 -    def test_elementtree_findall_ns_qname(self):
    2139          XML = self.etree.XML
    2140          ElementTree = self.etree.ElementTree
    2141          QName = self.etree.QName
    2142          tree = ElementTree(XML(
    2143                  _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')))
    2144          self.assertEquals(len(list(tree.findall(QName("b")))), 2)
    2145          self.assertEquals(len(list(tree.findall(QName("X", "b")))), 1)
    2146
    2147 -    def test_findall_ns(self):
    2148          XML = self.etree.XML
    2149          root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
    2150          self.assertEquals(len(root.findall(".//{X}b")), 2)
    2151          self.assertEquals(len(root.findall(".//{X}*")), 2)
    2152          self.assertEquals(len(root.findall(".//b")), 3)
    2153
    2154 -    def test_index(self):
    2155          etree = self.etree
    2156          e = etree.Element('foo')
    2157          for i in range(10):
    2158              etree.SubElement(e, 'a%s' % i)
    2159          for i in range(10):
    2160              self.assertEquals(
    2161                  i,
    2162                  e.index(e[i]))
    2163          self.assertEquals(
    2164              3, e.index(e[3], 3))
    2165          self.assertRaises(
    2166              ValueError, e.index, e[3], 4)
    2167          self.assertRaises(
    2168              ValueError, e.index, e[3], 0, 2)
    2169          self.assertRaises(
    2170              ValueError, e.index, e[8], 0, -3)
    2171          self.assertRaises(
    2172              ValueError, e.index, e[8], -5, -3)
    2173          self.assertEquals(
    2174              8, e.index(e[8], 0, -1))
    2175          self.assertEquals(
    2176              8, e.index(e[8], -12, -1))
    2177          self.assertEquals(
    2178              0, e.index(e[0], -12, -1))
    2179
    2180 -    def test_replace(self):
    2181          etree = self.etree
    2182          e = etree.Element('foo')
    2183          for i in range(10):
    2184              el = etree.SubElement(e, 'a%s' % i)
    2185              el.text = "text%d" % i
    2186              el.tail = "tail%d" % i
    2187
    2188          child0 = e[0]
    2189          child1 = e[1]
    2190          child2 = e[2]
    2191
    2192          e.replace(e[0], e[1])
    2193          self.assertEquals(
    2194              9, len(e))
    2195          self.assertEquals(
    2196              child1, e[0])
    2197          self.assertEquals(
    2198              child1.text, "text1")
    2199          self.assertEquals(
    2200              child1.tail, "tail1")
    2201          self.assertEquals(
    2202              child0.tail, "tail0")
    2203          self.assertEquals(
    2204              child2, e[1])
    2205
    2206          e.replace(e[-1], e[0])
    2207          self.assertEquals(
    2208              child1, e[-1])
    2209          self.assertEquals(
    2210              child1.text, "text1")
    2211          self.assertEquals(
    2212              child1.tail, "tail1")
    2213          self.assertEquals(
    2214              child2, e[0])
    2215
    2216 -    def test_replace_new(self):
    2217          etree = self.etree
    2218          e = etree.Element('foo')
    2219          for i in range(10):
    2220              etree.SubElement(e, 'a%s' % i)
    2221
    2222          new_element = etree.Element("test")
    2223          new_element.text = "TESTTEXT"
    2224          new_element.tail = "TESTTAIL"
    2225          child1 = e[1]
    2226          e.replace(e[0], new_element)
    2227          self.assertEquals(
    2228              new_element, e[0])
    2229          self.assertEquals(
    2230              "TESTTEXT",
    2231              e[0].text)
    2232          self.assertEquals(
    2233              "TESTTAIL",
    2234              e[0].tail)
    2235          self.assertEquals(
    2236              child1, e[1])
    2237
    2238 -    def test_setslice_all_empty_reversed(self):
    2239          Element = self.etree.Element
    2240          SubElement = self.etree.SubElement
    2241
    2242          a = Element('a')
    2243
    2244          e = Element('e')
    2245          f = Element('f')
    2246          g = Element('g')
    2247
    2248          s = [e, f, g]
    2249          a[::-1] = s
    2250          self.assertEquals(
    2251              [g, f, e],
    2252              list(a))
    2253
    2254 -    def test_setslice_step(self):
    2255          Element = self.etree.Element
    2256          SubElement = self.etree.SubElement
    2257
    2258          a = Element('a')
    2259          b = SubElement(a, 'b')
    2260          c = SubElement(a, 'c')
    2261          d = SubElement(a, 'd')
    2262          e = SubElement(a, 'e')
    2263
    2264          x = Element('x')
    2265          y = Element('y')
    2266
    2267          a[1::2] = [x, y]
    2268          self.assertEquals(
    2269              [b, x, d, y],
    2270              list(a))
    2271
    2272 -    def test_setslice_step_negative(self):
    2273          Element = self.etree.Element
    2274          SubElement = self.etree.SubElement
    2275
    2276          a = Element('a')
    2277          b = SubElement(a, 'b')
    2278          c = SubElement(a, 'c')
    2279          d = SubElement(a, 'd')
    2280          e = SubElement(a, 'e')
    2281
    2282          x = Element('x')
    2283          y = Element('y')
    2284
    2285          a[1::-1] = [x, y]
    2286          self.assertEquals(
    2287              [y, x, d, e],
    2288              list(a))
    2289
    2290 -    def test_setslice_step_negative2(self):
    2291          Element = self.etree.Element
    2292          SubElement = self.etree.SubElement
    2293
    2294          a = Element('a')
    2295          b = SubElement(a, 'b')
    2296          c = SubElement(a, 'c')
    2297          d = SubElement(a, 'd')
    2298          e = SubElement(a, 'e')
    2299
    2300          x = Element('x')
    2301          y = Element('y')
    2302
    2303          a[::-2] = [x, y]
    2304          self.assertEquals(
    2305              [b, y, d, x],
    2306              list(a))
    2307
    2308 -    def test_setslice_step_overrun(self):
    2309          Element = self.etree.Element
    2310          SubElement = self.etree.SubElement
    2311          try:
    2312              slice
    2313          except NameError:
    2314              print("slice() not found")
    2315              return
    2316
    2317          a = Element('a')
    2318          b = SubElement(a, 'b')
    2319          c = SubElement(a, 'c')
    2320          d = SubElement(a, 'd')
    2321          e = SubElement(a, 'e')
    2322
    2323          x = Element('x')
    2324          y = Element('y')
    2325          z = Element('z')
    2326
    2327          self.assertRaises(
    2328              ValueError,
    2329              operator.setitem, a, slice(1,None,2), [x, y, z])
    2330
    2331          self.assertEquals(
    2332              [b, c, d, e],
    2333              list(a))
    2334
    2335 -    def test_sourceline_XML(self):
    2336          XML = self.etree.XML
    2337          root = XML(_bytes('''<?xml version="1.0"?>
    2338          <root><test>
    2339
    2340          <bla/></test>
    2341          </root>
    2342          '''))
    2343
    2344          self.assertEquals(
    2345              [2, 2, 4],
    2346              [ el.sourceline for el in root.getiterator() ])
    2347
    2348 -    def test_sourceline_parse(self):
    2349          parse = self.etree.parse
    2350          tree = parse(fileInTestDir('include/test_xinclude.xml'))
    2351
    2352          self.assertEquals(
    2353              [1, 2, 3],
    2354              [ el.sourceline for el in tree.getiterator() ])
    2355
    2356 -    def test_sourceline_iterparse_end(self):
    2357          iterparse = self.etree.iterparse
    2358          lines = [ el.sourceline for (event, el) in
    2359                    iterparse(fileInTestDir('include/test_xinclude.xml')) ]
    2360
    2361          self.assertEquals(
    2362              [2, 3, 1],
    2363              lines)
    2364
    2365 -    def test_sourceline_iterparse_start(self):
    2366          iterparse = self.etree.iterparse
    2367          lines = [ el.sourceline for (event, el) in
    2368                    iterparse(fileInTestDir('include/test_xinclude.xml'),
    2369                              events=("start",)) ]
    2370
    2371          self.assertEquals(
    2372              [1, 2, 3],
    2373              lines)
    2374
    2375 -    def test_sourceline_element(self):
    2376          Element = self.etree.Element
    2377          SubElement = self.etree.SubElement
    2378          el = Element("test")
    2379          self.assertEquals(None, el.sourceline)
    2380
    2381          child = SubElement(el, "test")
    2382          self.assertEquals(None, el.sourceline)
    2383          self.assertEquals(None, child.sourceline)
    2384
    2385 -    def test_XML_base_url_docinfo(self):
    2386          etree = self.etree
    2387          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2388          docinfo = root.getroottree().docinfo
    2389          self.assertEquals(docinfo.URL, "http://no/such/url")
    2390
    2391 -    def test_XML_set_base_url_docinfo(self):
    2392          etree = self.etree
    2393          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2394          docinfo = root.getroottree().docinfo
    2395          self.assertEquals(docinfo.URL, "http://no/such/url")
    2396          docinfo.URL = "https://secret/url"
    2397          self.assertEquals(docinfo.URL, "https://secret/url")
    2398
    2399 -    def test_parse_stringio_base_url(self):
    2400          etree = self.etree
    2401          tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url")
    2402          docinfo = tree.docinfo
    2403          self.assertEquals(docinfo.URL, "http://no/such/url")
    2404
    2405 -    def test_parse_base_url_docinfo(self):
    2406          etree = self.etree
    2407          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
    2408                             base_url="http://no/such/url")
    2409          docinfo = tree.docinfo
    2410          self.assertEquals(docinfo.URL, "http://no/such/url")
    2411
    2412 -    def test_HTML_base_url_docinfo(self):
    2413          etree = self.etree
    2414          root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url")
    2415          docinfo = root.getroottree().docinfo
    2416          self.assertEquals(docinfo.URL, "http://no/such/url")
    2417
    2418 -    def test_docinfo_public(self):
    2419          etree = self.etree
    2420          xml_header = '<?xml version="1.0" encoding="ascii"?>'
    2421          pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
    2422          sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    2423          doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
    2424
    2425          xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
    2426
    2427          tree = etree.parse(BytesIO(xml))
    2428          docinfo = tree.docinfo
    2429          self.assertEquals(docinfo.encoding,    "ascii")
    2430          self.assertEquals(docinfo.xml_version, "1.0")
    2431          self.assertEquals(docinfo.public_id,   pub_id)
    2432          self.assertEquals(docinfo.system_url,  sys_id)
    2433          self.assertEquals(docinfo.root_name,   'html')
    2434          self.assertEquals(docinfo.doctype, doctype_string)
    2435
    2436 -    def test_docinfo_system(self):
    2437          etree = self.etree
    2438          xml_header = '<?xml version="1.0" encoding="UTF-8"?>'
    2439          sys_id = "some.dtd"
    2440          doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id
    2441          xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
    2442
    2443          tree = etree.parse(BytesIO(xml))
    2444          docinfo = tree.docinfo
    2445          self.assertEquals(docinfo.encoding,    "UTF-8")
    2446          self.assertEquals(docinfo.xml_version, "1.0")
    2447          self.assertEquals(docinfo.public_id,   None)
    2448          self.assertEquals(docinfo.system_url,  sys_id)
    2449          self.assertEquals(docinfo.root_name,   'html')
    2450          self.assertEquals(docinfo.doctype, doctype_string)
    2451
    2452 -    def test_docinfo_empty(self):
    2453          etree = self.etree
    2454          xml = _bytes('<html><body></body></html>')
    2455          tree = etree.parse(BytesIO(xml))
    2456          docinfo = tree.docinfo
    2457          self.assertEquals(docinfo.encoding,    "UTF-8")
    2458          self.assertEquals(docinfo.xml_version, "1.0")
    2459          self.assertEquals(docinfo.public_id,   None)
    2460          self.assertEquals(docinfo.system_url,  None)
    2461          self.assertEquals(docinfo.root_name,   'html')
    2462          self.assertEquals(docinfo.doctype, '')
    2463
    2464 -    def test_docinfo_name_only(self):
    2465          etree = self.etree
    2466          xml = _bytes('<!DOCTYPE root><root></root>')
    2467          tree = etree.parse(BytesIO(xml))
    2468          docinfo = tree.docinfo
    2469          self.assertEquals(docinfo.encoding,    "UTF-8")
    2470          self.assertEquals(docinfo.xml_version, "1.0")
    2471          self.assertEquals(docinfo.public_id,   None)
    2472          self.assertEquals(docinfo.system_url,  None)
    2473          self.assertEquals(docinfo.root_name,   'root')
    2474          self.assertEquals(docinfo.doctype, '<!DOCTYPE root>')
    2475
    2476 -    def test_doctype_name_only_roundtrip(self):
    2477          etree = self.etree
    2478          xml = _bytes('<!DOCTYPE root>\n<root/>')
    2479          tree = etree.parse(BytesIO(xml))
    2480          self.assertEquals(xml, etree.tostring(tree))
    2481
    2482 -    def test_doctype_output_override(self):
    2483          etree = self.etree
    2484          pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
    2485          sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    2486          doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
    2487
    2488          xml = _bytes('<!DOCTYPE root>\n<root/>')
    2489          tree = etree.parse(BytesIO(xml))
    2490          self.assertEquals(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
    2491                            etree.tostring(tree, doctype=doctype_string))
    2492
    2493 -    def test_xml_base(self):
    2494          etree = self.etree
    2495          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2496          self.assertEquals(root.base, "http://no/such/url")
    2497          self.assertEquals(
    2498              root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
    2499          root.base = "https://secret/url"
    2500          self.assertEquals(root.base, "https://secret/url")
    2501          self.assertEquals(
    2502              root.get('{http://www.w3.org/XML/1998/namespace}base'),
    2503              "https://secret/url")
    2504
    2505 -    def test_xml_base_attribute(self):
    2506          etree = self.etree
    2507          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2508          self.assertEquals(root.base, "http://no/such/url")
    2509          self.assertEquals(
    2510              root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
    2511          root.set('{http://www.w3.org/XML/1998/namespace}base',
    2512                   "https://secret/url")
    2513          self.assertEquals(root.base, "https://secret/url")
    2514          self.assertEquals(
    2515              root.get('{http://www.w3.org/XML/1998/namespace}base'),
    2516              "https://secret/url")
    2517
    2518 -    def test_html_base(self):
    2519          etree = self.etree
    2520          root = etree.HTML(_bytes("<html><body></body></html>"),
    2521                            base_url="http://no/such/url")
    2522          self.assertEquals(root.base, "http://no/such/url")
    2523
    2524 -    def test_html_base_tag(self):
    2525          etree = self.etree
    2526          root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>'))
    2527          self.assertEquals(root.base, "http://no/such/url")
    2528
    2529 -    def test_parse_fileobject_unicode(self):
    2530          # parse from a file object that returns unicode strings
    2531          f = LargeFileLikeUnicode()
    2532          tree = self.etree.parse(f)
    2533          root = tree.getroot()
    2534          self.assert_(root.tag.endswith('root'))
    2535
    2536 -    def test_dtd_io(self):
    2537          # check that DTDs that go in also go back out
    2538          xml = _bytes('''\
    2539          <!DOCTYPE test SYSTEM "test.dtd" [
    2540            <!ENTITY entity "tasty">
    2541            <!ELEMENT test (a)>
    2542            <!ELEMENT a (#PCDATA)>
    2543          ]>
    2544          <test><a>test-test</a></test>\
    2545          ''')
    2546          tree = self.etree.parse(BytesIO(xml))
    2547          self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")),
    2548                           xml.replace(_bytes(" "), _bytes("")))
    2549
    2550 -    def test_byte_zero(self):
    2551          Element = self.etree.Element
    2552
    2553          a = Element('a')
    2554          self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
    2555          self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
    2556
    2557          self.assertRaises(ValueError, Element, 'ha\0ho')
    2558
    2559 -    def test_unicode_byte_zero(self):
    2560          Element = self.etree.Element
    2561
    2562          a = Element('a')
    2563          self.assertRaises(ValueError, setattr, a, "text",
    2564                            _str('ha\0ho'))
    2565          self.assertRaises(ValueError, setattr, a, "tail",
    2566                            _str('ha\0ho'))
    2567
    2568          self.assertRaises(ValueError, Element,
    2569                            _str('ha\0ho'))
    2570
    2571 -    def test_byte_invalid(self):
    2572          Element = self.etree.Element
    2573
    2574          a = Element('a')
    2575          self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
    2576          self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
    2577
    2578          self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
    2579          self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
    2580
    2581          self.assertRaises(ValueError, Element, 'ha\x07ho')
    2582          self.assertRaises(ValueError, Element, 'ha\x02ho')
    2583
    2584 -    def test_unicode_byte_invalid(self):
    2585          Element = self.etree.Element
    2586
    2587          a = Element('a')
    2588          self.assertRaises(ValueError, setattr, a, "text",
    2589                            _str('ha\x07ho'))
    2590          self.assertRaises(ValueError, setattr, a, "text",
    2591                            _str('ha\x02ho'))
    2592
    2593          self.assertRaises(ValueError, setattr, a, "tail",
    2594                            _str('ha\x07ho'))
    2595          self.assertRaises(ValueError, setattr, a, "tail",
    2596                            _str('ha\x02ho'))
    2597
    2598          self.assertRaises(ValueError, Element,
    2599                            _str('ha\x07ho'))
    2600          self.assertRaises(ValueError, Element,
    2601                            _str('ha\x02ho'))
    2602
    2603 -    def test_unicode_byte_invalid_sequence(self):
    2604          Element = self.etree.Element
    2605
    2606          a = Element('a')
    2607          self.assertRaises(ValueError, setattr, a, "text",
    2608                            _str('ha\u1234\x07ho'))
    2609          self.assertRaises(ValueError, setattr, a, "text",
    2610                            _str('ha\u1234\x02ho'))
    2611
    2612          self.assertRaises(ValueError, setattr, a, "tail",
    2613                            _str('ha\u1234\x07ho'))
    2614          self.assertRaises(ValueError, setattr, a, "tail",
    2615                            _str('ha\u1234\x02ho'))
    2616
    2617          self.assertRaises(ValueError, Element,
    2618                            _str('ha\u1234\x07ho'))
    2619          self.assertRaises(ValueError, Element,
    2620                            _str('ha\u1234\x02ho'))
    2621
    2622 -    def test_encoding_tostring_utf16(self):
    2623          # ElementTree fails to serialize this
    2624          tostring = self.etree.tostring
    2625          Element = self.etree.Element
    2626          SubElement = self.etree.SubElement
    2627
    2628          a = Element('a')
    2629          b = SubElement(a, 'b')
    2630          c = SubElement(a, 'c')
    2631
    2632          result = tostring(a, encoding='UTF-16')
    2633          self.assertEquals(_bytes('<a><b></b><c></c></a>'),
    2634                            canonicalize(result))
    2635
    2636 -    def test_tostring_none(self):
    2637          # ElementTree raises an AssertionError here
    2638          tostring = self.etree.tostring
    2639          self.assertRaises(TypeError, self.etree.tostring, None)
    2640
    2641 -    def test_tostring_pretty(self):
    2642          tostring = self.etree.tostring
    2643          Element = self.etree.Element
    2644          SubElement = self.etree.SubElement
    2645
    2646          a = Element('a')
    2647          b = SubElement(a, 'b')
    2648          c = SubElement(a, 'c')
    2649
    2650          result = tostring(a)
    2651          self.assertEquals(result, _bytes("<a><b/><c/></a>"))
    2652
    2653          result = tostring(a, pretty_print=False)
    2654          self.assertEquals(result, _bytes("<a><b/><c/></a>"))
    2655
    2656          result = tostring(a, pretty_print=True)
    2657          self.assertEquals(result, _bytes("<a>\n  <b/>\n  <c/>\n</a>\n"))
    2658
    2659 -    def test_tostring_with_tail(self):
    2660          tostring = self.etree.tostring
    2661          Element = self.etree.Element
    2662          SubElement = self.etree.SubElement
    2663
    2664          a = Element('a')
    2665          a.tail = "aTAIL"
    2666          b = SubElement(a, 'b')
    2667          b.tail = "bTAIL"
    2668          c = SubElement(a, 'c')
    2669
    2670          result = tostring(a)
    2671          self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
    2672
    2673          result = tostring(a, with_tail=False)
    2674          self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>"))
    2675
    2676          result = tostring(a, with_tail=True)
    2677          self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
    2678
    2679 -    def test_standalone(self):
    2680          tostring = self.etree.tostring
    2681          XML = self.etree.XML
    2682          ElementTree = self.etree.ElementTree
    2683          Element = self.etree.Element
    2684
    2685          tree = Element("root").getroottree()
    2686          self.assertEquals(None, tree.docinfo.standalone)
    2687
    2688          tree = XML(_bytes("<root/>")).getroottree()
    2689          self.assertEquals(None, tree.docinfo.standalone)
    2690
    2691          tree = XML(_bytes(
    2692              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"
    2693              )).getroottree()
    2694          self.assertEquals(True, tree.docinfo.standalone)
    2695
    2696          tree = XML(_bytes(
    2697              "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"
    2698              )).getroottree()
    2699          self.assertEquals(False, tree.docinfo.standalone)
    2700
    2701 -    def test_tostring_standalone(self):
    2702          tostring = self.etree.tostring
    2703          XML = self.etree.XML
    2704          ElementTree = self.etree.ElementTree
    2705
    2706          root = XML(_bytes("<root/>"))
    2707
    2708          tree = ElementTree(root)
    2709          self.assertEquals(None, tree.docinfo.standalone)
    2710
    2711          result = tostring(root, xml_declaration=True, encoding="ASCII")
    2712          self.assertEquals(result, _bytes(
    2713              "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
    2714
    2715          result = tostring(root, xml_declaration=True, encoding="ASCII",
    2716                            standalone=True)
    2717          self.assertEquals(result, _bytes(
    2718              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
    2719
    2720          tree = ElementTree(XML(result))
    2721          self.assertEquals(True, tree.docinfo.standalone)
    2722
    2723          result = tostring(root, xml_declaration=True, encoding="ASCII",
    2724                            standalone=False)
    2725          self.assertEquals(result, _bytes(
    2726              "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
    2727
    2728          tree = ElementTree(XML(result))
    2729          self.assertEquals(False, tree.docinfo.standalone)
    2730
    2731 -    def test_tostring_standalone_in_out(self):
    2732          tostring = self.etree.tostring
    2733          XML = self.etree.XML
    2734          ElementTree = self.etree.ElementTree
    2735
    2736          root = XML(_bytes(
    2737              "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>"))
    2738
    2739          tree = ElementTree(root)
    2740          self.assertEquals(True, tree.docinfo.standalone)
    2741
    2742          result = tostring(root, xml_declaration=True, encoding="ASCII")
    2743          self.assertEquals(result, _bytes(
    2744              "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
    2745
    2746          result = tostring(root, xml_declaration=True, encoding="ASCII",
    2747                            standalone=True)
    2748          self.assertEquals(result, _bytes(
    2749              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
    2750
    2751 -    def test_tostring_method_text_encoding(self):
    2752          tostring = self.etree.tostring
    2753          Element = self.etree.Element
    2754          SubElement = self.etree.SubElement
    2755
    2756          a = Element('a')
    2757          a.text = "A"
    2758          a.tail = "tail"
    2759          b = SubElement(a, 'b')
    2760          b.text = "B"
    2761          b.tail = _str("Søk på nettet")
    2762          c = SubElement(a, 'c')
    2763          c.text = "C"
    2764
    2765          result = tostring(a, method="text", encoding="UTF-16")
    2766
    2767          self.assertEquals(_str('ABSøk på nettetCtail').encode("UTF-16"),
    2768                            result)
    2769
    2770 -    def test_tostring_method_text_unicode(self):
    2771          tostring = self.etree.tostring
    2772          Element = self.etree.Element
    2773          SubElement = self.etree.SubElement
    2774
    2775          a = Element('a')
    2776          a.text = _str('Søk på nettetA')
    2777          a.tail = "tail"
    2778          b = SubElement(a, 'b')
    2779          b.text = "B"
    2780          b.tail = _str('Søk på nettetB')
    2781          c = SubElement(a, 'c')
    2782          c.text = "C"
    2783
    2784          self.assertRaises(UnicodeEncodeError,
    2785                            tostring, a, method="text")
    2786
    2787          self.assertEquals(
    2788              _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
    2789              tostring(a, encoding="UTF-8", method="text"))
    2790
    2791 -    def test_tounicode(self):
    2792          tounicode = self.etree.tounicode
    2793          Element = self.etree.Element
    2794          SubElement = self.etree.SubElement
    2795
    2796          a = Element('a')
    2797          b = SubElement(a, 'b')
    2798          c = SubElement(a, 'c')
    2799
    2800          self.assert_(isinstance(tounicode(a), _unicode))
    2801          self.assertEquals(_bytes('<a><b></b><c></c></a>'),
    2802                            canonicalize(tounicode(a)))
    2803
    2804 -    def test_tounicode_element(self):
    2805          tounicode = self.etree.tounicode
    2806          Element = self.etree.Element
    2807          SubElement = self.etree.SubElement
    2808
    2809          a = Element('a')
    2810          b = SubElement(a, 'b')
    2811          c = SubElement(a, 'c')
    2812          d = SubElement(c, 'd')
    2813          self.assert_(isinstance(tounicode(b), _unicode))
    2814          self.assert_(isinstance(tounicode(c), _unicode))
    2815          self.assertEquals(_bytes('<b></b>'),
    2816                            canonicalize(tounicode(b)))
    2817          self.assertEquals(_bytes('<c><d></d></c>'),
    2818                            canonicalize(tounicode(c)))
    2819
    2820 -    def test_tounicode_none(self):
    2821          tounicode = self.etree.tounicode
    2822          self.assertRaises(TypeError, self.etree.tounicode, None)
    2823
    2824 -    def test_tounicode_element_tail(self):
    2825          tounicode = self.etree.tounicode
    2826          Element = self.etree.Element
    2827          SubElement = self.etree.SubElement
    2828
    2829          a = Element('a')
    2830          b = SubElement(a, 'b')
    2831          c = SubElement(a, 'c')
    2832          d = SubElement(c, 'd')
    2833          b.tail = 'Foo'
    2834
    2835          self.assert_(isinstance(tounicode(b), _unicode))
    2836          self.assert_(tounicode(b) == '<b/>Foo' or
    2837                       tounicode(b) == '<b />Foo')
    2838
    2839 -    def test_tounicode_pretty(self):
    2840          tounicode = self.etree.tounicode
    2841          Element = self.etree.Element
    2842          SubElement = self.etree.SubElement
    2843
    2844          a = Element('a')
    2845          b = SubElement(a, 'b')
    2846          c = SubElement(a, 'c')
    2847
    2848          result = tounicode(a)
    2849          self.assertEquals(result, "<a><b/><c/></a>")
    2850
    2851          result = tounicode(a, pretty_print=False)
    2852          self.assertEquals(result, "<a><b/><c/></a>")
    2853
    2854          result = tounicode(a, pretty_print=True)
    2855          self.assertEquals(result, "<a>\n  <b/>\n  <c/>\n</a>\n")
    2856
    2857 -    def test_tostring_unicode(self):
    2858          tostring = self.etree.tostring
    2859          Element = self.etree.Element
    2860          SubElement = self.etree.SubElement
    2861
    2862          a = Element('a')
    2863          b = SubElement(a, 'b')
    2864          c = SubElement(a, 'c')
    2865
    2866          self.assert_(isinstance(tostring(a, encoding=_unicode), _unicode))
    2867          self.assertEquals(_bytes('<a><b></b><c></c></a>'),
    2868                            canonicalize(tostring(a, encoding=_unicode)))
    2869
    2870 -    def test_tostring_unicode_element(self):
    2871          tostring = self.etree.tostring
    2872          Element = self.etree.Element
    2873          SubElement = self.etree.SubElement
    2874
    2875          a = Element('a')
    2876          b = SubElement(a, 'b')
    2877          c = SubElement(a, 'c')
    2878          d = SubElement(c, 'd')
    2879          self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode))
    2880          self.assert_(isinstance(tostring(c, encoding=_unicode), _unicode))
    2881          self.assertEquals(_bytes('<b></b>'),
    2882                            canonicalize(tostring(b, encoding=_unicode)))
    2883          self.assertEquals(_bytes('<c><d></d></c>'),
    2884                            canonicalize(tostring(c, encoding=_unicode)))
    2885
    2886 -    def test_tostring_unicode_none(self):
    2887          tostring = self.etree.tostring
    2888          self.assertRaises(TypeError, self.etree.tostring,
    2889                            None, encoding=_unicode)
    2890
    2891 -    def test_tostring_unicode_element_tail(self):
    2892          tostring = self.etree.tostring
    2893          Element = self.etree.Element
    2894          SubElement = self.etree.SubElement
    2895
    2896          a = Element('a')
    2897          b = SubElement(a, 'b')
    2898          c = SubElement(a, 'c')
    2899          d = SubElement(c, 'd')
    2900          b.tail = 'Foo'
    2901
    2902          self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode))
    2903          self.assert_(tostring(b, encoding=_unicode) == '<b/>Foo' or
    2904                       tostring(b, encoding=_unicode) == '<b />Foo')
    2905
    2906 -    def test_tostring_unicode_pretty(self):
    2907          tostring = self.etree.tostring
    2908          Element = self.etree.Element
    2909          SubElement = self.etree.SubElement
    2910
    2911          a = Element('a')
    2912          b = SubElement(a, 'b')
    2913          c = SubElement(a, 'c')
    2914
    2915          result = tostring(a, encoding=_unicode)
    2916          self.assertEquals(result, "<a><b/><c/></a>")
    2917
    2918          result = tostring(a, encoding=_unicode, pretty_print=False)
    2919          self.assertEquals(result, "<a><b/><c/></a>")
    2920
    2921          result = tostring(a, encoding=_unicode, pretty_print=True)
    2922          self.assertEquals(result, "<a>\n  <b/>\n  <c/>\n</a>\n")
    2923
    2924      # helper methods
    2925
    2926 -    def _writeElement(self, element, encoding='us-ascii', compression=0):
    2927          """Write out element for comparison.
    2928          """
    2929          ElementTree = self.etree.ElementTree
    2930          f = BytesIO()
    2931          tree = ElementTree(element=element)
    2932          tree.write(f, encoding=encoding, compression=compression)
    2933          data = f.getvalue()
    2934          if compression:
    2935              data = zlib.decompress(data)
    2936          return canonicalize(data)
    2937
    2938
    2939 -class XIncludeTestCase(HelperTestCase):
    2940 -    def test_xinclude_text(self):
    2941          filename = fileInTestDir('test_broken.xml')
    2942          root = etree.XML(_bytes('''\
    2943          <doc xmlns:xi="http://www.w3.org/2001/XInclude">
    2944            <xi:include href="%s" parse="text"/>
    2945          </doc>
    2946          ''' % filename))
    2947          old_text = root.text
    2948          content = read_file(filename)
    2949          old_tail = root[0].tail
    2950
    2951          self.include( etree.ElementTree(root) )
    2952          self.assertEquals(old_text + content + old_tail,
    2953                            root.text)
    2954
    2955 -    def test_xinclude(self):
    2956          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'))
    2957          self.assertNotEquals(
    2958              'a',
    2959              tree.getroot()[1].tag)
    2960          # process xincludes
    2961          self.include( tree )
    2962          # check whether we find it replaced with included data
    2963          self.assertEquals(
    2964              'a',
    2965              tree.getroot()[1].tag)
    2966
    2967 -    def test_xinclude_resolver(self):
    2968          class res(etree.Resolver):
    2969              include_text = read_file(fileInTestDir('test.xml'))
    2970              called = {}
    2971              def resolve(self, url, id, context):
    2972                  if url.endswith(".dtd"):
    2973                      self.called["dtd"] = True
    2974                      return self.resolve_filename(
    2975                          fileInTestDir('test.dtd'), context)
    2976                  elif url.endswith("test_xinclude.xml"):
    2977                      self.called["input"] = True
    2978                      return None # delegate to default resolver
    2979                  else:
    2980                      self.called["include"] = True
    2981                      return self.resolve_string(self.include_text, context)
    2982
    2983          res_instance = res()
    2984          parser = etree.XMLParser(load_dtd = True)
    2985          parser.resolvers.add(res_instance)
    2986
    2987          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
    2988                             parser = parser)
    2989
    2990          self.include(tree)
    2991
    2992          called = list(res_instance.called.items())
    2993          called.sort()
    2994          self.assertEquals(
    2995              [("dtd", True), ("include", True), ("input", True)],
    2996              called)
    2997
    2998 -class ETreeXIncludeTestCase(XIncludeTestCase):
    2999 -    def include(self, tree):
    3000          tree.xinclude()
    3001
    3002
    3003 -class ElementIncludeTestCase(XIncludeTestCase):
    3004      from lxml import ElementInclude
    3005 -    def include(self, tree):
    3006          self.ElementInclude.include(tree.getroot())
    3007
    3008
    3009 -class ETreeC14NTestCase(HelperTestCase):
    3010 -    def test_c14n(self):
    3011          tree = self.parse(_bytes('<a><b/></a>'))
    3012          f = BytesIO()
    3013          tree.write_c14n(f)
    3014          s = f.getvalue()
    3015          self.assertEquals(_bytes('<a><b></b></a>'),
    3016                            s)
    3017
    3018 -    def test_c14n_gzip(self):
    3019          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3020          f = BytesIO()
    3021          tree.write_c14n(f, compression=9)
    3022          gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
    3023          try:
    3024              s = gzfile.read()
    3025          finally:
    3026              gzfile.close()
    3027          self.assertEquals(_bytes('<a>'+'<b></b>'*200+'</a>'),
    3028                            s)
    3029
    3030 -    def test_c14n_file(self):
    3031          tree = self.parse(_bytes('<a><b/></a>'))
    3032          handle, filename = tempfile.mkstemp()
    3033          try:
    3034              tree.write_c14n(filename)
    3035              data = read_file(filename, 'rb')
    3036          finally:
    3037              os.close(handle)
    3038              os.remove(filename)
    3039          self.assertEquals(_bytes('<a><b></b></a>'),
    3040                            data)
    3041
    3042 -    def test_c14n_file_gzip(self):
    3043          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3044          handle, filename = tempfile.mkstemp()
    3045          try:
    3046              tree.write_c14n(filename, compression=9)
    3047              f = gzip.open(filename, 'rb')
    3048              try:
    3049                  data = f.read()
    3050              finally:
    3051                  f.close()
    3052          finally:
    3053              os.close(handle)
    3054              os.remove(filename)
    3055          self.assertEquals(_bytes('<a>'+'<b></b>'*200+'</a>'),
    3056                            data)
    3057
    3058 -    def test_c14n_with_comments(self):
    3059          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
    3060          f = BytesIO()
    3061          tree.write_c14n(f)
    3062          s = f.getvalue()
    3063          self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
    3064                            s)
    3065          f = BytesIO()
    3066          tree.write_c14n(f, with_comments=True)
    3067          s = f.getvalue()
    3068          self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
    3069                            s)
    3070          f = BytesIO()
    3071          tree.write_c14n(f, with_comments=False)
    3072          s = f.getvalue()
    3073          self.assertEquals(_bytes('<a><b></b></a>'),
    3074                            s)
    3075
    3076 -    def test_c14n_tostring_with_comments(self):
    3077          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
    3078          s = etree.tostring(tree, method='c14n')
    3079          self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
    3080                            s)
    3081          s = etree.tostring(tree, method='c14n', with_comments=True)
    3082          self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
    3083                            s)
    3084          s = etree.tostring(tree, method='c14n', with_comments=False)
    3085          self.assertEquals(_bytes('<a><b></b></a>'),
    3086                            s)
    3087
    3088 -    def test_c14n_element_tostring_with_comments(self):
    3089          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
    3090          s = etree.tostring(tree.getroot(), method='c14n')
    3091          self.assertEquals(_bytes('<a><!--ho--><b></b></a>'),
    3092                            s)
    3093          s = etree.tostring(tree.getroot(), method='c14n', with_comments=True)
    3094          self.assertEquals(_bytes('<a><!--ho--><b></b></a>'),
    3095                            s)
    3096          s = etree.tostring(tree.getroot(), method='c14n', with_comments=False)
    3097          self.assertEquals(_bytes('<a><b></b></a>'),
    3098                            s)
    3099
    3100 -    def test_c14n_exclusive(self):
    3101          tree = self.parse(_bytes(
    3102                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
    3103          f = BytesIO()
    3104          tree.write_c14n(f)
    3105          s = f.getvalue()
    3106          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3107                            s)
    3108          f = BytesIO()
    3109          tree.write_c14n(f, exclusive=False)
    3110          s = f.getvalue()
    3111          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3112                            s)
    3113          f = BytesIO()
    3114          tree.write_c14n(f, exclusive=True)
    3115          s = f.getvalue()
    3116          self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
    3117                            s)
    3118
    3119 -    def test_c14n_tostring_exclusive(self):
    3120          tree = self.parse(_bytes(
    3121                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
    3122          s = etree.tostring(tree, method='c14n')
    3123          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3124                            s)
    3125          s = etree.tostring(tree, method='c14n', exclusive=False)
    3126          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3127                            s)
    3128          s = etree.tostring(tree, method='c14n', exclusive=True)
    3129          self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
    3130                            s)
    3131
    3132 -    def test_c14n_element_tostring_exclusive(self):
    3133          tree = self.parse(_bytes(
    3134                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
    3135          s = etree.tostring(tree.getroot(), method='c14n')
    3136          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3137                            s)
    3138          s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
    3139          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3140                            s)
    3141          s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
    3142          self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
    3143                            s)
    3144
    3145          s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
    3146          self.assertEquals(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
    3147                            s)
    3148          s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
    3149          self.assertEquals(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
    3150                            s)
    3151
    3152
    3153 -class ETreeWriteTestCase(HelperTestCase):
    3154 -    def test_write(self):
    3155          tree = self.parse(_bytes('<a><b/></a>'))
    3156          f = BytesIO()
    3157          tree.write(f)
    3158          s = f.getvalue()
    3159          self.assertEquals(_bytes('<a><b/></a>'),
    3160                            s)
    3161
    3162 -    def test_write_gzip(self):
    3163          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3164          f = BytesIO()
    3165          tree.write(f, compression=9)
    3166          gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
    3167          try:
    3168              s = gzfile.read()
    3169          finally:
    3170              gzfile.close()
    3171          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3172                            s)
    3173
    3174 -    def test_write_gzip_level(self):
    3175          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3176          f = BytesIO()
    3177          tree.write(f, compression=0)
    3178          s0 = f.getvalue()
    3179
    3180          f = BytesIO()
    3181          tree.write(f)
    3182          self.assertEquals(f.getvalue(), s0)
    3183
    3184          f = BytesIO()
    3185          tree.write(f, compression=1)
    3186          s = f.getvalue()
    3187          self.assert_(len(s) <= len(s0))
    3188          gzfile = gzip.GzipFile(fileobj=BytesIO(s))
    3189          try:
    3190              s1 = gzfile.read()
    3191          finally:
    3192              gzfile.close()
    3193
    3194          f = BytesIO()
    3195          tree.write(f, compression=9)
    3196          s = f.getvalue()
    3197          self.assert_(len(s) <= len(s0))
    3198          gzfile = gzip.GzipFile(fileobj=BytesIO(s))
    3199          try:
    3200              s9 = gzfile.read()
    3201          finally:
    3202              gzfile.close()
    3203
    3204          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3205                            s0)
    3206          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3207                            s1)
    3208          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3209                            s9)
    3210
    3211 -    def test_write_file(self):
    3212          tree = self.parse(_bytes('<a><b/></a>'))
    3213          handle, filename = tempfile.mkstemp()
    3214          try:
    3215              tree.write(filename)
    3216              data = read_file(filename, 'rb')
    3217          finally:
    3218              os.close(handle)
    3219              os.remove(filename)
    3220          self.assertEquals(_bytes('<a><b/></a>'),
    3221                            data)
    3222
    3223 -    def test_write_file_gzip(self):
    3224          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3225          handle, filename = tempfile.mkstemp()
    3226          try:
    3227              tree.write(filename, compression=9)
    3228              f = gzip.open(filename, 'rb')
    3229              try:
    3230                  data = f.read()
    3231              finally:
    3232                  f.close()
    3233          finally:
    3234              os.close(handle)
    3235              os.remove(filename)
    3236          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3237                            data)
    3238
    3239 -    def test_write_file_gzip_parse(self):
    3240          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3241          handle, filename = tempfile.mkstemp()
    3242          try:
    3243              tree.write(filename, compression=9)
    3244              data = etree.tostring(etree.parse(filename))
    3245          finally:
    3246              os.close(handle)
    3247              os.remove(filename)
    3248          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3249                            data)
    3250
    3251 -    def test_write_file_gzipfile_parse(self):
    3252          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3253          handle, filename = tempfile.mkstemp()
    3254          try:
    3255              tree.write(filename, compression=9)
    3256              data = etree.tostring(etree.parse(
    3257                  gzip.GzipFile(filename)))
    3258          finally:
    3259              os.close(handle)
    3260              os.remove(filename)
    3261          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3262                            data)
    3263
    3264 -class ETreeErrorLogTest(HelperTestCase):
    3265      etree = etree
    3266
    3267 -    def test_parse_error_logging(self):
    3268          parse = self.etree.parse
    3269          f = BytesIO('<a><b></c></b></a>')
    3270          self.etree.clear_error_log()
    3271          try:
    3272              parse(f)
    3273              logs = None
    3274          except SyntaxError:
    3275              e = sys.exc_info()[1]
    3276              logs = e.error_log
    3277          f.close()
    3278          self.assert_([ log for log in logs
    3279                         if 'mismatch' in log.message ])
    3280          self.assert_([ log for log in logs
    3281                         if 'PARSER'   in log.domain_name])
    3282          self.assert_([ log for log in logs
    3283                         if 'ERR_TAG_NAME_MISMATCH' in log.type_name ])
    3284          self.assert_([ log for log in logs
    3285                         if 1 == log.line ])
    3286          self.assert_([ log for log in logs
    3287                         if 15 == log.column ])
    3288
    3289 -    def _test_python_error_logging(self):
    3290          """This can't really be tested as long as there isn't a way to
    3291          reset the logging setup ...
    3292          """
    3293          parse = self.etree.parse
    3294
    3295          messages = []
    3296          class Logger(self.etree.PyErrorLog):
    3297              def log(self, entry, message, *args):
    3298                  messages.append(message)
    3299
    3300          self.etree.use_global_python_log(Logger())
    3301          f = BytesIO('<a><b></c></b></a>')
    3302          try:
    3303              parse(f)
    3304          except SyntaxError:
    3305              pass
    3306          f.close()
    3307
    3308          self.assert_([ message for message in messages
    3309                         if 'mismatch' in message ])
    3310          self.assert_([ message for message in messages
    3311                         if ':PARSER:'   in message])
    3312          self.assert_([ message for message in messages
    3313                         if ':ERR_TAG_NAME_MISMATCH:' in message ])
    3314          self.assert_([ message for message in messages
    3315                         if ':1:15:' in message ])
    3316
    3317 -def test_suite():
    3318      suite = unittest.TestSuite()
    3319      suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)])
    3320      suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)])
    3321      suite.addTests([unittest.makeSuite(ElementIncludeTestCase)])
    3322      suite.addTests([unittest.makeSuite(ETreeC14NTestCase)])
    3323      suite.addTests([unittest.makeSuite(ETreeWriteTestCase)])
    3324      suite.addTests([unittest.makeSuite(ETreeErrorLogTest)])
    3325      suite.addTests(
    3326          [make_doctest('../../../doc/tutorial.txt')])
    3327      suite.addTests(
    3328          [make_doctest('../../../doc/api.txt')])
    3329      suite.addTests(
    3330          [make_doctest('../../../doc/FAQ.txt')])
    3331      suite.addTests(
    3332          [make_doctest('../../../doc/parsing.txt')])
    3333      suite.addTests(
    3334          [make_doctest('../../../doc/resolvers.txt')])
    3335      return suite
    3336
    3337  if __name__ == '__main__':
    3338      print('to test use test.py %s' % __file__)
    3339