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