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_getiterator_filter_namespace(self):
    2062          Element = self.etree.Element
    2063          SubElement = self.etree.SubElement
    2064
    2065          a = Element('{a}a')
    2066          b = SubElement(a, '{a}b')
    2067          c = SubElement(a, '{a}c')
    2068          d = SubElement(b, '{b}d')
    2069          e = SubElement(c, '{a}e')
    2070          f = SubElement(c, '{b}f')
    2071
    2072          self.assertEquals(
    2073              [a],
    2074              list(a.getiterator('{a}a')))
    2075          self.assertEquals(
    2076              [],
    2077              list(a.getiterator('{b}a')))
    2078          self.assertEquals(
    2079              [],
    2080              list(a.getiterator('a')))
    2081          self.assertEquals(
    2082              [f],
    2083              list(c.getiterator('{b}*')))
    2084          self.assertEquals(
    2085              [d, f],
    2086              list(a.getiterator('{b}*')))
    2087
    2088 -    def test_getiterator_filter_entities(self):
    2089          Element = self.etree.Element
    2090          Entity = self.etree.Entity
    2091          SubElement = self.etree.SubElement
    2092
    2093          a = Element('a')
    2094          b = SubElement(a, 'b')
    2095          entity_b = Entity("TEST-b")
    2096          b.append(entity_b)
    2097
    2098          self.assertEquals(
    2099              [entity_b],
    2100              list(a.getiterator(Entity)))
    2101
    2102          entity_a = Entity("TEST-a")
    2103          a.append(entity_a)
    2104
    2105          self.assertEquals(
    2106              [entity_b, entity_a],
    2107              list(a.getiterator(Entity)))
    2108
    2109          self.assertEquals(
    2110              [entity_b],
    2111              list(b.getiterator(Entity)))
    2112
    2113 -    def test_getiterator_filter_element(self):
    2114          Element = self.etree.Element
    2115          Comment = self.etree.Comment
    2116          PI = self.etree.PI
    2117          SubElement = self.etree.SubElement
    2118
    2119          a = Element('a')
    2120          b = SubElement(a, 'b')
    2121          a.append(Comment("test"))
    2122          a.append(PI("pi", "content"))
    2123          c = SubElement(a, 'c')
    2124
    2125          self.assertEquals(
    2126              [a, b, c],
    2127              list(a.getiterator(Element)))
    2128
    2129 -    def test_getiterator_filter_all_comment_pi(self):
    2130          # ElementTree iterates over everything here
    2131          Element = self.etree.Element
    2132          Comment = self.etree.Comment
    2133          PI = self.etree.PI
    2134          SubElement = self.etree.SubElement
    2135
    2136          a = Element('a')
    2137          b = SubElement(a, 'b')
    2138          a.append(Comment("test"))
    2139          a.append(PI("pi", "content"))
    2140          c = SubElement(a, 'c')
    2141
    2142          self.assertEquals(
    2143              [a, b, c],
    2144              list(a.getiterator('*')))
    2145
    2146 -    def test_elementtree_find_qname(self):
    2147          XML = self.etree.XML
    2148          ElementTree = self.etree.ElementTree
    2149          QName = self.etree.QName
    2150          tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
    2151          self.assertEquals(tree.find(QName("c")), tree.getroot()[2])
    2152
    2153 -    def test_elementtree_findall_qname(self):
    2154          XML = self.etree.XML
    2155          ElementTree = self.etree.ElementTree
    2156          QName = self.etree.QName
    2157          tree = ElementTree(XML(_bytes('<a><b><c/></b><b/><c><b/></c></a>')))
    2158          self.assertEquals(len(list(tree.findall(QName("c")))), 1)
    2159
    2160 -    def test_elementtree_findall_ns_qname(self):
    2161          XML = self.etree.XML
    2162          ElementTree = self.etree.ElementTree
    2163          QName = self.etree.QName
    2164          tree = ElementTree(XML(
    2165                  _bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>')))
    2166          self.assertEquals(len(list(tree.findall(QName("b")))), 2)
    2167          self.assertEquals(len(list(tree.findall(QName("X", "b")))), 1)
    2168
    2169 -    def test_findall_ns(self):
    2170          XML = self.etree.XML
    2171          root = XML(_bytes('<a xmlns:x="X" xmlns:y="Y"><x:b><c/></x:b><b/><c><x:b/><b/></c><b/></a>'))
    2172          self.assertEquals(len(root.findall(".//{X}b")), 2)
    2173          self.assertEquals(len(root.findall(".//{X}*")), 2)
    2174          self.assertEquals(len(root.findall(".//b")), 3)
    2175
    2176 -    def test_index(self):
    2177          etree = self.etree
    2178          e = etree.Element('foo')
    2179          for i in range(10):
    2180              etree.SubElement(e, 'a%s' % i)
    2181          for i in range(10):
    2182              self.assertEquals(
    2183                  i,
    2184                  e.index(e[i]))
    2185          self.assertEquals(
    2186              3, e.index(e[3], 3))
    2187          self.assertRaises(
    2188              ValueError, e.index, e[3], 4)
    2189          self.assertRaises(
    2190              ValueError, e.index, e[3], 0, 2)
    2191          self.assertRaises(
    2192              ValueError, e.index, e[8], 0, -3)
    2193          self.assertRaises(
    2194              ValueError, e.index, e[8], -5, -3)
    2195          self.assertEquals(
    2196              8, e.index(e[8], 0, -1))
    2197          self.assertEquals(
    2198              8, e.index(e[8], -12, -1))
    2199          self.assertEquals(
    2200              0, e.index(e[0], -12, -1))
    2201
    2202 -    def test_replace(self):
    2203          etree = self.etree
    2204          e = etree.Element('foo')
    2205          for i in range(10):
    2206              el = etree.SubElement(e, 'a%s' % i)
    2207              el.text = "text%d" % i
    2208              el.tail = "tail%d" % i
    2209
    2210          child0 = e[0]
    2211          child1 = e[1]
    2212          child2 = e[2]
    2213
    2214          e.replace(e[0], e[1])
    2215          self.assertEquals(
    2216              9, len(e))
    2217          self.assertEquals(
    2218              child1, e[0])
    2219          self.assertEquals(
    2220              child1.text, "text1")
    2221          self.assertEquals(
    2222              child1.tail, "tail1")
    2223          self.assertEquals(
    2224              child0.tail, "tail0")
    2225          self.assertEquals(
    2226              child2, e[1])
    2227
    2228          e.replace(e[-1], e[0])
    2229          self.assertEquals(
    2230              child1, e[-1])
    2231          self.assertEquals(
    2232              child1.text, "text1")
    2233          self.assertEquals(
    2234              child1.tail, "tail1")
    2235          self.assertEquals(
    2236              child2, e[0])
    2237
    2238 -    def test_replace_new(self):
    2239          etree = self.etree
    2240          e = etree.Element('foo')
    2241          for i in range(10):
    2242              etree.SubElement(e, 'a%s' % i)
    2243
    2244          new_element = etree.Element("test")
    2245          new_element.text = "TESTTEXT"
    2246          new_element.tail = "TESTTAIL"
    2247          child1 = e[1]
    2248          e.replace(e[0], new_element)
    2249          self.assertEquals(
    2250              new_element, e[0])
    2251          self.assertEquals(
    2252              "TESTTEXT",
    2253              e[0].text)
    2254          self.assertEquals(
    2255              "TESTTAIL",
    2256              e[0].tail)
    2257          self.assertEquals(
    2258              child1, e[1])
    2259
    2260 -    def test_setslice_all_empty_reversed(self):
    2261          Element = self.etree.Element
    2262          SubElement = self.etree.SubElement
    2263
    2264          a = Element('a')
    2265
    2266          e = Element('e')
    2267          f = Element('f')
    2268          g = Element('g')
    2269
    2270          s = [e, f, g]
    2271          a[::-1] = s
    2272          self.assertEquals(
    2273              [g, f, e],
    2274              list(a))
    2275
    2276 -    def test_setslice_step(self):
    2277          Element = self.etree.Element
    2278          SubElement = self.etree.SubElement
    2279
    2280          a = Element('a')
    2281          b = SubElement(a, 'b')
    2282          c = SubElement(a, 'c')
    2283          d = SubElement(a, 'd')
    2284          e = SubElement(a, 'e')
    2285
    2286          x = Element('x')
    2287          y = Element('y')
    2288
    2289          a[1::2] = [x, y]
    2290          self.assertEquals(
    2291              [b, x, d, y],
    2292              list(a))
    2293
    2294 -    def test_setslice_step_negative(self):
    2295          Element = self.etree.Element
    2296          SubElement = self.etree.SubElement
    2297
    2298          a = Element('a')
    2299          b = SubElement(a, 'b')
    2300          c = SubElement(a, 'c')
    2301          d = SubElement(a, 'd')
    2302          e = SubElement(a, 'e')
    2303
    2304          x = Element('x')
    2305          y = Element('y')
    2306
    2307          a[1::-1] = [x, y]
    2308          self.assertEquals(
    2309              [y, x, d, e],
    2310              list(a))
    2311
    2312 -    def test_setslice_step_negative2(self):
    2313          Element = self.etree.Element
    2314          SubElement = self.etree.SubElement
    2315
    2316          a = Element('a')
    2317          b = SubElement(a, 'b')
    2318          c = SubElement(a, 'c')
    2319          d = SubElement(a, 'd')
    2320          e = SubElement(a, 'e')
    2321
    2322          x = Element('x')
    2323          y = Element('y')
    2324
    2325          a[::-2] = [x, y]
    2326          self.assertEquals(
    2327              [b, y, d, x],
    2328              list(a))
    2329
    2330 -    def test_setslice_step_overrun(self):
    2331          Element = self.etree.Element
    2332          SubElement = self.etree.SubElement
    2333          try:
    2334              slice
    2335          except NameError:
    2336              print("slice() not found")
    2337              return
    2338
    2339          a = Element('a')
    2340          b = SubElement(a, 'b')
    2341          c = SubElement(a, 'c')
    2342          d = SubElement(a, 'd')
    2343          e = SubElement(a, 'e')
    2344
    2345          x = Element('x')
    2346          y = Element('y')
    2347          z = Element('z')
    2348
    2349          self.assertRaises(
    2350              ValueError,
    2351              operator.setitem, a, slice(1,None,2), [x, y, z])
    2352
    2353          self.assertEquals(
    2354              [b, c, d, e],
    2355              list(a))
    2356
    2357 -    def test_sourceline_XML(self):
    2358          XML = self.etree.XML
    2359          root = XML(_bytes('''<?xml version="1.0"?>
    2360          <root><test>
    2361
    2362          <bla/></test>
    2363          </root>
    2364          '''))
    2365
    2366          self.assertEquals(
    2367              [2, 2, 4],
    2368              [ el.sourceline for el in root.getiterator() ])
    2369
    2370 -    def test_sourceline_parse(self):
    2371          parse = self.etree.parse
    2372          tree = parse(fileInTestDir('include/test_xinclude.xml'))
    2373
    2374          self.assertEquals(
    2375              [1, 2, 3],
    2376              [ el.sourceline for el in tree.getiterator() ])
    2377
    2378 -    def test_sourceline_iterparse_end(self):
    2379          iterparse = self.etree.iterparse
    2380          lines = [ el.sourceline for (event, el) in
    2381                    iterparse(fileInTestDir('include/test_xinclude.xml')) ]
    2382
    2383          self.assertEquals(
    2384              [2, 3, 1],
    2385              lines)
    2386
    2387 -    def test_sourceline_iterparse_start(self):
    2388          iterparse = self.etree.iterparse
    2389          lines = [ el.sourceline for (event, el) in
    2390                    iterparse(fileInTestDir('include/test_xinclude.xml'),
    2391                              events=("start",)) ]
    2392
    2393          self.assertEquals(
    2394              [1, 2, 3],
    2395              lines)
    2396
    2397 -    def test_sourceline_element(self):
    2398          Element = self.etree.Element
    2399          SubElement = self.etree.SubElement
    2400          el = Element("test")
    2401          self.assertEquals(None, el.sourceline)
    2402
    2403          child = SubElement(el, "test")
    2404          self.assertEquals(None, el.sourceline)
    2405          self.assertEquals(None, child.sourceline)
    2406
    2407 -    def test_XML_base_url_docinfo(self):
    2408          etree = self.etree
    2409          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2410          docinfo = root.getroottree().docinfo
    2411          self.assertEquals(docinfo.URL, "http://no/such/url")
    2412
    2413 -    def test_XML_set_base_url_docinfo(self):
    2414          etree = self.etree
    2415          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2416          docinfo = root.getroottree().docinfo
    2417          self.assertEquals(docinfo.URL, "http://no/such/url")
    2418          docinfo.URL = "https://secret/url"
    2419          self.assertEquals(docinfo.URL, "https://secret/url")
    2420
    2421 -    def test_parse_stringio_base_url(self):
    2422          etree = self.etree
    2423          tree = etree.parse(BytesIO("<root/>"), base_url="http://no/such/url")
    2424          docinfo = tree.docinfo
    2425          self.assertEquals(docinfo.URL, "http://no/such/url")
    2426
    2427 -    def test_parse_base_url_docinfo(self):
    2428          etree = self.etree
    2429          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
    2430                             base_url="http://no/such/url")
    2431          docinfo = tree.docinfo
    2432          self.assertEquals(docinfo.URL, "http://no/such/url")
    2433
    2434 -    def test_HTML_base_url_docinfo(self):
    2435          etree = self.etree
    2436          root = etree.HTML(_bytes("<html/>"), base_url="http://no/such/url")
    2437          docinfo = root.getroottree().docinfo
    2438          self.assertEquals(docinfo.URL, "http://no/such/url")
    2439
    2440 -    def test_docinfo_public(self):
    2441          etree = self.etree
    2442          xml_header = '<?xml version="1.0" encoding="ascii"?>'
    2443          pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
    2444          sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    2445          doctype_string = '<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id)
    2446
    2447          xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
    2448
    2449          tree = etree.parse(BytesIO(xml))
    2450          docinfo = tree.docinfo
    2451          self.assertEquals(docinfo.encoding,    "ascii")
    2452          self.assertEquals(docinfo.xml_version, "1.0")
    2453          self.assertEquals(docinfo.public_id,   pub_id)
    2454          self.assertEquals(docinfo.system_url,  sys_id)
    2455          self.assertEquals(docinfo.root_name,   'html')
    2456          self.assertEquals(docinfo.doctype, doctype_string)
    2457
    2458 -    def test_docinfo_system(self):
    2459          etree = self.etree
    2460          xml_header = '<?xml version="1.0" encoding="UTF-8"?>'
    2461          sys_id = "some.dtd"
    2462          doctype_string = '<!DOCTYPE html SYSTEM "%s">' % sys_id
    2463          xml = _bytes(xml_header + doctype_string + '<html><body></body></html>')
    2464
    2465          tree = etree.parse(BytesIO(xml))
    2466          docinfo = tree.docinfo
    2467          self.assertEquals(docinfo.encoding,    "UTF-8")
    2468          self.assertEquals(docinfo.xml_version, "1.0")
    2469          self.assertEquals(docinfo.public_id,   None)
    2470          self.assertEquals(docinfo.system_url,  sys_id)
    2471          self.assertEquals(docinfo.root_name,   'html')
    2472          self.assertEquals(docinfo.doctype, doctype_string)
    2473
    2474 -    def test_docinfo_empty(self):
    2475          etree = self.etree
    2476          xml = _bytes('<html><body></body></html>')
    2477          tree = etree.parse(BytesIO(xml))
    2478          docinfo = tree.docinfo
    2479          self.assertEquals(docinfo.encoding,    "UTF-8")
    2480          self.assertEquals(docinfo.xml_version, "1.0")
    2481          self.assertEquals(docinfo.public_id,   None)
    2482          self.assertEquals(docinfo.system_url,  None)
    2483          self.assertEquals(docinfo.root_name,   'html')
    2484          self.assertEquals(docinfo.doctype, '')
    2485
    2486 -    def test_docinfo_name_only(self):
    2487          etree = self.etree
    2488          xml = _bytes('<!DOCTYPE root><root></root>')
    2489          tree = etree.parse(BytesIO(xml))
    2490          docinfo = tree.docinfo
    2491          self.assertEquals(docinfo.encoding,    "UTF-8")
    2492          self.assertEquals(docinfo.xml_version, "1.0")
    2493          self.assertEquals(docinfo.public_id,   None)
    2494          self.assertEquals(docinfo.system_url,  None)
    2495          self.assertEquals(docinfo.root_name,   'root')
    2496          self.assertEquals(docinfo.doctype, '<!DOCTYPE root>')
    2497
    2498 -    def test_doctype_name_only_roundtrip(self):
    2499          etree = self.etree
    2500          xml = _bytes('<!DOCTYPE root>\n<root/>')
    2501          tree = etree.parse(BytesIO(xml))
    2502          self.assertEquals(xml, etree.tostring(tree))
    2503
    2504 -    def test_doctype_output_override(self):
    2505          etree = self.etree
    2506          pub_id = "-//W3C//DTD XHTML 1.0 Transitional//EN"
    2507          sys_id = "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
    2508          doctype_string = _bytes('<!DOCTYPE html PUBLIC "%s" "%s">' % (pub_id, sys_id))
    2509
    2510          xml = _bytes('<!DOCTYPE root>\n<root/>')
    2511          tree = etree.parse(BytesIO(xml))
    2512          self.assertEquals(xml.replace(_bytes('<!DOCTYPE root>'), doctype_string),
    2513                            etree.tostring(tree, doctype=doctype_string))
    2514
    2515 -    def test_xml_base(self):
    2516          etree = self.etree
    2517          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2518          self.assertEquals(root.base, "http://no/such/url")
    2519          self.assertEquals(
    2520              root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
    2521          root.base = "https://secret/url"
    2522          self.assertEquals(root.base, "https://secret/url")
    2523          self.assertEquals(
    2524              root.get('{http://www.w3.org/XML/1998/namespace}base'),
    2525              "https://secret/url")
    2526
    2527 -    def test_xml_base_attribute(self):
    2528          etree = self.etree
    2529          root = etree.XML(_bytes("<root/>"), base_url="http://no/such/url")
    2530          self.assertEquals(root.base, "http://no/such/url")
    2531          self.assertEquals(
    2532              root.get('{http://www.w3.org/XML/1998/namespace}base'), None)
    2533          root.set('{http://www.w3.org/XML/1998/namespace}base',
    2534                   "https://secret/url")
    2535          self.assertEquals(root.base, "https://secret/url")
    2536          self.assertEquals(
    2537              root.get('{http://www.w3.org/XML/1998/namespace}base'),
    2538              "https://secret/url")
    2539
    2540 -    def test_html_base(self):
    2541          etree = self.etree
    2542          root = etree.HTML(_bytes("<html><body></body></html>"),
    2543                            base_url="http://no/such/url")
    2544          self.assertEquals(root.base, "http://no/such/url")
    2545
    2546 -    def test_html_base_tag(self):
    2547          etree = self.etree
    2548          root = etree.HTML(_bytes('<html><head><base href="http://no/such/url"></head></html>'))
    2549          self.assertEquals(root.base, "http://no/such/url")
    2550
    2551 -    def test_parse_fileobject_unicode(self):
    2552          # parse from a file object that returns unicode strings
    2553          f = LargeFileLikeUnicode()
    2554          tree = self.etree.parse(f)
    2555          root = tree.getroot()
    2556          self.assert_(root.tag.endswith('root'))
    2557
    2558 -    def test_dtd_io(self):
    2559          # check that DTDs that go in also go back out
    2560          xml = _bytes('''\
    2561          <!DOCTYPE test SYSTEM "test.dtd" [
    2562            <!ENTITY entity "tasty">
    2563            <!ELEMENT test (a)>
    2564            <!ELEMENT a (#PCDATA)>
    2565          ]>
    2566          <test><a>test-test</a></test>\
    2567          ''')
    2568          tree = self.etree.parse(BytesIO(xml))
    2569          self.assertEqual(self.etree.tostring(tree).replace(_bytes(" "), _bytes("")),
    2570                           xml.replace(_bytes(" "), _bytes("")))
    2571
    2572 -    def test_byte_zero(self):
    2573          Element = self.etree.Element
    2574
    2575          a = Element('a')
    2576          self.assertRaises(ValueError, setattr, a, "text", 'ha\0ho')
    2577          self.assertRaises(ValueError, setattr, a, "tail", 'ha\0ho')
    2578
    2579          self.assertRaises(ValueError, Element, 'ha\0ho')
    2580
    2581 -    def test_unicode_byte_zero(self):
    2582          Element = self.etree.Element
    2583
    2584          a = Element('a')
    2585          self.assertRaises(ValueError, setattr, a, "text",
    2586                            _str('ha\0ho'))
    2587          self.assertRaises(ValueError, setattr, a, "tail",
    2588                            _str('ha\0ho'))
    2589
    2590          self.assertRaises(ValueError, Element,
    2591                            _str('ha\0ho'))
    2592
    2593 -    def test_byte_invalid(self):
    2594          Element = self.etree.Element
    2595
    2596          a = Element('a')
    2597          self.assertRaises(ValueError, setattr, a, "text", 'ha\x07ho')
    2598          self.assertRaises(ValueError, setattr, a, "text", 'ha\x02ho')
    2599
    2600          self.assertRaises(ValueError, setattr, a, "tail", 'ha\x07ho')
    2601          self.assertRaises(ValueError, setattr, a, "tail", 'ha\x02ho')
    2602
    2603          self.assertRaises(ValueError, Element, 'ha\x07ho')
    2604          self.assertRaises(ValueError, Element, 'ha\x02ho')
    2605
    2606 -    def test_unicode_byte_invalid(self):
    2607          Element = self.etree.Element
    2608
    2609          a = Element('a')
    2610          self.assertRaises(ValueError, setattr, a, "text",
    2611                            _str('ha\x07ho'))
    2612          self.assertRaises(ValueError, setattr, a, "text",
    2613                            _str('ha\x02ho'))
    2614
    2615          self.assertRaises(ValueError, setattr, a, "tail",
    2616                            _str('ha\x07ho'))
    2617          self.assertRaises(ValueError, setattr, a, "tail",
    2618                            _str('ha\x02ho'))
    2619
    2620          self.assertRaises(ValueError, Element,
    2621                            _str('ha\x07ho'))
    2622          self.assertRaises(ValueError, Element,
    2623                            _str('ha\x02ho'))
    2624
    2625 -    def test_unicode_byte_invalid_sequence(self):
    2626          Element = self.etree.Element
    2627
    2628          a = Element('a')
    2629          self.assertRaises(ValueError, setattr, a, "text",
    2630                            _str('ha\u1234\x07ho'))
    2631          self.assertRaises(ValueError, setattr, a, "text",
    2632                            _str('ha\u1234\x02ho'))
    2633
    2634          self.assertRaises(ValueError, setattr, a, "tail",
    2635                            _str('ha\u1234\x07ho'))
    2636          self.assertRaises(ValueError, setattr, a, "tail",
    2637                            _str('ha\u1234\x02ho'))
    2638
    2639          self.assertRaises(ValueError, Element,
    2640                            _str('ha\u1234\x07ho'))
    2641          self.assertRaises(ValueError, Element,
    2642                            _str('ha\u1234\x02ho'))
    2643
    2644 -    def test_encoding_tostring_utf16(self):
    2645          # ElementTree fails to serialize this
    2646          tostring = self.etree.tostring
    2647          Element = self.etree.Element
    2648          SubElement = self.etree.SubElement
    2649
    2650          a = Element('a')
    2651          b = SubElement(a, 'b')
    2652          c = SubElement(a, 'c')
    2653
    2654          result = tostring(a, encoding='UTF-16')
    2655          self.assertEquals(_bytes('<a><b></b><c></c></a>'),
    2656                            canonicalize(result))
    2657
    2658 -    def test_tostring_none(self):
    2659          # ElementTree raises an AssertionError here
    2660          tostring = self.etree.tostring
    2661          self.assertRaises(TypeError, self.etree.tostring, None)
    2662
    2663 -    def test_tostring_pretty(self):
    2664          tostring = self.etree.tostring
    2665          Element = self.etree.Element
    2666          SubElement = self.etree.SubElement
    2667
    2668          a = Element('a')
    2669          b = SubElement(a, 'b')
    2670          c = SubElement(a, 'c')
    2671
    2672          result = tostring(a)
    2673          self.assertEquals(result, _bytes("<a><b/><c/></a>"))
    2674
    2675          result = tostring(a, pretty_print=False)
    2676          self.assertEquals(result, _bytes("<a><b/><c/></a>"))
    2677
    2678          result = tostring(a, pretty_print=True)
    2679          self.assertEquals(result, _bytes("<a>\n  <b/>\n  <c/>\n</a>\n"))
    2680
    2681 -    def test_tostring_with_tail(self):
    2682          tostring = self.etree.tostring
    2683          Element = self.etree.Element
    2684          SubElement = self.etree.SubElement
    2685
    2686          a = Element('a')
    2687          a.tail = "aTAIL"
    2688          b = SubElement(a, 'b')
    2689          b.tail = "bTAIL"
    2690          c = SubElement(a, 'c')
    2691
    2692          result = tostring(a)
    2693          self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
    2694
    2695          result = tostring(a, with_tail=False)
    2696          self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>"))
    2697
    2698          result = tostring(a, with_tail=True)
    2699          self.assertEquals(result, _bytes("<a><b/>bTAIL<c/></a>aTAIL"))
    2700
    2701 -    def test_standalone(self):
    2702          tostring = self.etree.tostring
    2703          XML = self.etree.XML
    2704          ElementTree = self.etree.ElementTree
    2705          Element = self.etree.Element
    2706
    2707          tree = Element("root").getroottree()
    2708          self.assertEquals(None, tree.docinfo.standalone)
    2709
    2710          tree = XML(_bytes("<root/>")).getroottree()
    2711          self.assertEquals(None, tree.docinfo.standalone)
    2712
    2713          tree = XML(_bytes(
    2714              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"
    2715              )).getroottree()
    2716          self.assertEquals(True, tree.docinfo.standalone)
    2717
    2718          tree = XML(_bytes(
    2719              "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"
    2720              )).getroottree()
    2721          self.assertEquals(False, tree.docinfo.standalone)
    2722
    2723 -    def test_tostring_standalone(self):
    2724          tostring = self.etree.tostring
    2725          XML = self.etree.XML
    2726          ElementTree = self.etree.ElementTree
    2727
    2728          root = XML(_bytes("<root/>"))
    2729
    2730          tree = ElementTree(root)
    2731          self.assertEquals(None, tree.docinfo.standalone)
    2732
    2733          result = tostring(root, xml_declaration=True, encoding="ASCII")
    2734          self.assertEquals(result, _bytes(
    2735              "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
    2736
    2737          result = tostring(root, xml_declaration=True, encoding="ASCII",
    2738                            standalone=True)
    2739          self.assertEquals(result, _bytes(
    2740              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
    2741
    2742          tree = ElementTree(XML(result))
    2743          self.assertEquals(True, tree.docinfo.standalone)
    2744
    2745          result = tostring(root, xml_declaration=True, encoding="ASCII",
    2746                            standalone=False)
    2747          self.assertEquals(result, _bytes(
    2748              "<?xml version='1.0' encoding='ASCII' standalone='no'?>\n<root/>"))
    2749
    2750          tree = ElementTree(XML(result))
    2751          self.assertEquals(False, tree.docinfo.standalone)
    2752
    2753 -    def test_tostring_standalone_in_out(self):
    2754          tostring = self.etree.tostring
    2755          XML = self.etree.XML
    2756          ElementTree = self.etree.ElementTree
    2757
    2758          root = XML(_bytes(
    2759              "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>\n<root/>"))
    2760
    2761          tree = ElementTree(root)
    2762          self.assertEquals(True, tree.docinfo.standalone)
    2763
    2764          result = tostring(root, xml_declaration=True, encoding="ASCII")
    2765          self.assertEquals(result, _bytes(
    2766              "<?xml version='1.0' encoding='ASCII'?>\n<root/>"))
    2767
    2768          result = tostring(root, xml_declaration=True, encoding="ASCII",
    2769                            standalone=True)
    2770          self.assertEquals(result, _bytes(
    2771              "<?xml version='1.0' encoding='ASCII' standalone='yes'?>\n<root/>"))
    2772
    2773 -    def test_tostring_method_text_encoding(self):
    2774          tostring = self.etree.tostring
    2775          Element = self.etree.Element
    2776          SubElement = self.etree.SubElement
    2777
    2778          a = Element('a')
    2779          a.text = "A"
    2780          a.tail = "tail"
    2781          b = SubElement(a, 'b')
    2782          b.text = "B"
    2783          b.tail = _str("Søk på nettet")
    2784          c = SubElement(a, 'c')
    2785          c.text = "C"
    2786
    2787          result = tostring(a, method="text", encoding="UTF-16")
    2788
    2789          self.assertEquals(_str('ABSøk på nettetCtail').encode("UTF-16"),
    2790                            result)
    2791
    2792 -    def test_tostring_method_text_unicode(self):
    2793          tostring = self.etree.tostring
    2794          Element = self.etree.Element
    2795          SubElement = self.etree.SubElement
    2796
    2797          a = Element('a')
    2798          a.text = _str('Søk på nettetA')
    2799          a.tail = "tail"
    2800          b = SubElement(a, 'b')
    2801          b.text = "B"
    2802          b.tail = _str('Søk på nettetB')
    2803          c = SubElement(a, 'c')
    2804          c.text = "C"
    2805
    2806          self.assertRaises(UnicodeEncodeError,
    2807                            tostring, a, method="text")
    2808
    2809          self.assertEquals(
    2810              _str('Søk på nettetABSøk på nettetBCtail').encode('utf-8'),
    2811              tostring(a, encoding="UTF-8", method="text"))
    2812
    2813 -    def test_tounicode(self):
    2814          tounicode = self.etree.tounicode
    2815          Element = self.etree.Element
    2816          SubElement = self.etree.SubElement
    2817
    2818          a = Element('a')
    2819          b = SubElement(a, 'b')
    2820          c = SubElement(a, 'c')
    2821
    2822          self.assert_(isinstance(tounicode(a), _unicode))
    2823          self.assertEquals(_bytes('<a><b></b><c></c></a>'),
    2824                            canonicalize(tounicode(a)))
    2825
    2826 -    def test_tounicode_element(self):
    2827          tounicode = self.etree.tounicode
    2828          Element = self.etree.Element
    2829          SubElement = self.etree.SubElement
    2830
    2831          a = Element('a')
    2832          b = SubElement(a, 'b')
    2833          c = SubElement(a, 'c')
    2834          d = SubElement(c, 'd')
    2835          self.assert_(isinstance(tounicode(b), _unicode))
    2836          self.assert_(isinstance(tounicode(c), _unicode))
    2837          self.assertEquals(_bytes('<b></b>'),
    2838                            canonicalize(tounicode(b)))
    2839          self.assertEquals(_bytes('<c><d></d></c>'),
    2840                            canonicalize(tounicode(c)))
    2841
    2842 -    def test_tounicode_none(self):
    2843          tounicode = self.etree.tounicode
    2844          self.assertRaises(TypeError, self.etree.tounicode, None)
    2845
    2846 -    def test_tounicode_element_tail(self):
    2847          tounicode = self.etree.tounicode
    2848          Element = self.etree.Element
    2849          SubElement = self.etree.SubElement
    2850
    2851          a = Element('a')
    2852          b = SubElement(a, 'b')
    2853          c = SubElement(a, 'c')
    2854          d = SubElement(c, 'd')
    2855          b.tail = 'Foo'
    2856
    2857          self.assert_(isinstance(tounicode(b), _unicode))
    2858          self.assert_(tounicode(b) == '<b/>Foo' or
    2859                       tounicode(b) == '<b />Foo')
    2860
    2861 -    def test_tounicode_pretty(self):
    2862          tounicode = self.etree.tounicode
    2863          Element = self.etree.Element
    2864          SubElement = self.etree.SubElement
    2865
    2866          a = Element('a')
    2867          b = SubElement(a, 'b')
    2868          c = SubElement(a, 'c')
    2869
    2870          result = tounicode(a)
    2871          self.assertEquals(result, "<a><b/><c/></a>")
    2872
    2873          result = tounicode(a, pretty_print=False)
    2874          self.assertEquals(result, "<a><b/><c/></a>")
    2875
    2876          result = tounicode(a, pretty_print=True)
    2877          self.assertEquals(result, "<a>\n  <b/>\n  <c/>\n</a>\n")
    2878
    2879 -    def test_tostring_unicode(self):
    2880          tostring = self.etree.tostring
    2881          Element = self.etree.Element
    2882          SubElement = self.etree.SubElement
    2883
    2884          a = Element('a')
    2885          b = SubElement(a, 'b')
    2886          c = SubElement(a, 'c')
    2887
    2888          self.assert_(isinstance(tostring(a, encoding=_unicode), _unicode))
    2889          self.assertEquals(_bytes('<a><b></b><c></c></a>'),
    2890                            canonicalize(tostring(a, encoding=_unicode)))
    2891
    2892 -    def test_tostring_unicode_element(self):
    2893          tostring = self.etree.tostring
    2894          Element = self.etree.Element
    2895          SubElement = self.etree.SubElement
    2896
    2897          a = Element('a')
    2898          b = SubElement(a, 'b')
    2899          c = SubElement(a, 'c')
    2900          d = SubElement(c, 'd')
    2901          self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode))
    2902          self.assert_(isinstance(tostring(c, encoding=_unicode), _unicode))
    2903          self.assertEquals(_bytes('<b></b>'),
    2904                            canonicalize(tostring(b, encoding=_unicode)))
    2905          self.assertEquals(_bytes('<c><d></d></c>'),
    2906                            canonicalize(tostring(c, encoding=_unicode)))
    2907
    2908 -    def test_tostring_unicode_none(self):
    2909          tostring = self.etree.tostring
    2910          self.assertRaises(TypeError, self.etree.tostring,
    2911                            None, encoding=_unicode)
    2912
    2913 -    def test_tostring_unicode_element_tail(self):
    2914          tostring = self.etree.tostring
    2915          Element = self.etree.Element
    2916          SubElement = self.etree.SubElement
    2917
    2918          a = Element('a')
    2919          b = SubElement(a, 'b')
    2920          c = SubElement(a, 'c')
    2921          d = SubElement(c, 'd')
    2922          b.tail = 'Foo'
    2923
    2924          self.assert_(isinstance(tostring(b, encoding=_unicode), _unicode))
    2925          self.assert_(tostring(b, encoding=_unicode) == '<b/>Foo' or
    2926                       tostring(b, encoding=_unicode) == '<b />Foo')
    2927
    2928 -    def test_tostring_unicode_pretty(self):
    2929          tostring = self.etree.tostring
    2930          Element = self.etree.Element
    2931          SubElement = self.etree.SubElement
    2932
    2933          a = Element('a')
    2934          b = SubElement(a, 'b')
    2935          c = SubElement(a, 'c')
    2936
    2937          result = tostring(a, encoding=_unicode)
    2938          self.assertEquals(result, "<a><b/><c/></a>")
    2939
    2940          result = tostring(a, encoding=_unicode, pretty_print=False)
    2941          self.assertEquals(result, "<a><b/><c/></a>")
    2942
    2943          result = tostring(a, encoding=_unicode, pretty_print=True)
    2944          self.assertEquals(result, "<a>\n  <b/>\n  <c/>\n</a>\n")
    2945
    2946      # helper methods
    2947
    2948 -    def _writeElement(self, element, encoding='us-ascii', compression=0):
    2949          """Write out element for comparison.
    2950          """
    2951          ElementTree = self.etree.ElementTree
    2952          f = BytesIO()
    2953          tree = ElementTree(element=element)
    2954          tree.write(f, encoding=encoding, compression=compression)
    2955          data = f.getvalue()
    2956          if compression:
    2957              data = zlib.decompress(data)
    2958          return canonicalize(data)
    2959
    2960
    2961 -class XIncludeTestCase(HelperTestCase):
    2962 -    def test_xinclude_text(self):
    2963          filename = fileInTestDir('test_broken.xml')
    2964          root = etree.XML(_bytes('''\
    2965          <doc xmlns:xi="http://www.w3.org/2001/XInclude">
    2966            <xi:include href="%s" parse="text"/>
    2967          </doc>
    2968          ''' % filename))
    2969          old_text = root.text
    2970          content = read_file(filename)
    2971          old_tail = root[0].tail
    2972
    2973          self.include( etree.ElementTree(root) )
    2974          self.assertEquals(old_text + content + old_tail,
    2975                            root.text)
    2976
    2977 -    def test_xinclude(self):
    2978          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'))
    2979          self.assertNotEquals(
    2980              'a',
    2981              tree.getroot()[1].tag)
    2982          # process xincludes
    2983          self.include( tree )
    2984          # check whether we find it replaced with included data
    2985          self.assertEquals(
    2986              'a',
    2987              tree.getroot()[1].tag)
    2988
    2989 -    def test_xinclude_resolver(self):
    2990          class res(etree.Resolver):
    2991              include_text = read_file(fileInTestDir('test.xml'))
    2992              called = {}
    2993              def resolve(self, url, id, context):
    2994                  if url.endswith(".dtd"):
    2995                      self.called["dtd"] = True
    2996                      return self.resolve_filename(
    2997                          fileInTestDir('test.dtd'), context)
    2998                  elif url.endswith("test_xinclude.xml"):
    2999                      self.called["input"] = True
    3000                      return None # delegate to default resolver
    3001                  else:
    3002                      self.called["include"] = True
    3003                      return self.resolve_string(self.include_text, context)
    3004
    3005          res_instance = res()
    3006          parser = etree.XMLParser(load_dtd = True)
    3007          parser.resolvers.add(res_instance)
    3008
    3009          tree = etree.parse(fileInTestDir('include/test_xinclude.xml'),
    3010                             parser = parser)
    3011
    3012          self.include(tree)
    3013
    3014          called = list(res_instance.called.items())
    3015          called.sort()
    3016          self.assertEquals(
    3017              [("dtd", True), ("include", True), ("input", True)],
    3018              called)
    3019
    3020 -class ETreeXIncludeTestCase(XIncludeTestCase):
    3021 -    def include(self, tree):
    3022          tree.xinclude()
    3023
    3024
    3025 -class ElementIncludeTestCase(XIncludeTestCase):
    3026      from lxml import ElementInclude
    3027 -    def include(self, tree):
    3028          self.ElementInclude.include(tree.getroot())
    3029
    3030
    3031 -class ETreeC14NTestCase(HelperTestCase):
    3032 -    def test_c14n(self):
    3033          tree = self.parse(_bytes('<a><b/></a>'))
    3034          f = BytesIO()
    3035          tree.write_c14n(f)
    3036          s = f.getvalue()
    3037          self.assertEquals(_bytes('<a><b></b></a>'),
    3038                            s)
    3039
    3040 -    def test_c14n_gzip(self):
    3041          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3042          f = BytesIO()
    3043          tree.write_c14n(f, compression=9)
    3044          gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
    3045          try:
    3046              s = gzfile.read()
    3047          finally:
    3048              gzfile.close()
    3049          self.assertEquals(_bytes('<a>'+'<b></b>'*200+'</a>'),
    3050                            s)
    3051
    3052 -    def test_c14n_file(self):
    3053          tree = self.parse(_bytes('<a><b/></a>'))
    3054          handle, filename = tempfile.mkstemp()
    3055          try:
    3056              tree.write_c14n(filename)
    3057              data = read_file(filename, 'rb')
    3058          finally:
    3059              os.close(handle)
    3060              os.remove(filename)
    3061          self.assertEquals(_bytes('<a><b></b></a>'),
    3062                            data)
    3063
    3064 -    def test_c14n_file_gzip(self):
    3065          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3066          handle, filename = tempfile.mkstemp()
    3067          try:
    3068              tree.write_c14n(filename, compression=9)
    3069              f = gzip.open(filename, 'rb')
    3070              try:
    3071                  data = f.read()
    3072              finally:
    3073                  f.close()
    3074          finally:
    3075              os.close(handle)
    3076              os.remove(filename)
    3077          self.assertEquals(_bytes('<a>'+'<b></b>'*200+'</a>'),
    3078                            data)
    3079
    3080 -    def test_c14n_with_comments(self):
    3081          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
    3082          f = BytesIO()
    3083          tree.write_c14n(f)
    3084          s = f.getvalue()
    3085          self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
    3086                            s)
    3087          f = BytesIO()
    3088          tree.write_c14n(f, with_comments=True)
    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=False)
    3094          s = f.getvalue()
    3095          self.assertEquals(_bytes('<a><b></b></a>'),
    3096                            s)
    3097
    3098 -    def test_c14n_tostring_with_comments(self):
    3099          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
    3100          s = etree.tostring(tree, method='c14n')
    3101          self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
    3102                            s)
    3103          s = etree.tostring(tree, method='c14n', with_comments=True)
    3104          self.assertEquals(_bytes('<!--hi-->\n<a><!--ho--><b></b></a>\n<!--hu-->'),
    3105                            s)
    3106          s = etree.tostring(tree, method='c14n', with_comments=False)
    3107          self.assertEquals(_bytes('<a><b></b></a>'),
    3108                            s)
    3109
    3110 -    def test_c14n_element_tostring_with_comments(self):
    3111          tree = self.parse(_bytes('<!--hi--><a><!--ho--><b/></a><!--hu-->'))
    3112          s = etree.tostring(tree.getroot(), method='c14n')
    3113          self.assertEquals(_bytes('<a><!--ho--><b></b></a>'),
    3114                            s)
    3115          s = etree.tostring(tree.getroot(), method='c14n', with_comments=True)
    3116          self.assertEquals(_bytes('<a><!--ho--><b></b></a>'),
    3117                            s)
    3118          s = etree.tostring(tree.getroot(), method='c14n', with_comments=False)
    3119          self.assertEquals(_bytes('<a><b></b></a>'),
    3120                            s)
    3121
    3122 -    def test_c14n_exclusive(self):
    3123          tree = self.parse(_bytes(
    3124                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
    3125          f = BytesIO()
    3126          tree.write_c14n(f)
    3127          s = f.getvalue()
    3128          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3129                            s)
    3130          f = BytesIO()
    3131          tree.write_c14n(f, exclusive=False)
    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=True)
    3137          s = f.getvalue()
    3138          self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
    3139                            s)
    3140
    3141 -    def test_c14n_tostring_exclusive(self):
    3142          tree = self.parse(_bytes(
    3143                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
    3144          s = etree.tostring(tree, method='c14n')
    3145          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3146                            s)
    3147          s = etree.tostring(tree, method='c14n', exclusive=False)
    3148          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3149                            s)
    3150          s = etree.tostring(tree, method='c14n', exclusive=True)
    3151          self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
    3152                            s)
    3153
    3154 -    def test_c14n_element_tostring_exclusive(self):
    3155          tree = self.parse(_bytes(
    3156                  '<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b/></a>'))
    3157          s = etree.tostring(tree.getroot(), method='c14n')
    3158          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3159                            s)
    3160          s = etree.tostring(tree.getroot(), method='c14n', exclusive=False)
    3161          self.assertEquals(_bytes('<a xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"><z:b></z:b></a>'),
    3162                            s)
    3163          s = etree.tostring(tree.getroot(), method='c14n', exclusive=True)
    3164          self.assertEquals(_bytes('<a xmlns="http://abc"><z:b xmlns:z="http://cde"></z:b></a>'),
    3165                            s)
    3166
    3167          s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=False)
    3168          self.assertEquals(_bytes('<z:b xmlns="http://abc" xmlns:y="http://bcd" xmlns:z="http://cde"></z:b>'),
    3169                            s)
    3170          s = etree.tostring(tree.getroot()[0], method='c14n', exclusive=True)
    3171          self.assertEquals(_bytes('<z:b xmlns:z="http://cde"></z:b>'),
    3172                            s)
    3173
    3174
    3175 -class ETreeWriteTestCase(HelperTestCase):
    3176 -    def test_write(self):
    3177          tree = self.parse(_bytes('<a><b/></a>'))
    3178          f = BytesIO()
    3179          tree.write(f)
    3180          s = f.getvalue()
    3181          self.assertEquals(_bytes('<a><b/></a>'),
    3182                            s)
    3183
    3184 -    def test_write_gzip(self):
    3185          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3186          f = BytesIO()
    3187          tree.write(f, compression=9)
    3188          gzfile = gzip.GzipFile(fileobj=BytesIO(f.getvalue()))
    3189          try:
    3190              s = gzfile.read()
    3191          finally:
    3192              gzfile.close()
    3193          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3194                            s)
    3195
    3196 -    def test_write_gzip_level(self):
    3197          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3198          f = BytesIO()
    3199          tree.write(f, compression=0)
    3200          s0 = f.getvalue()
    3201
    3202          f = BytesIO()
    3203          tree.write(f)
    3204          self.assertEquals(f.getvalue(), s0)
    3205
    3206          f = BytesIO()
    3207          tree.write(f, compression=1)
    3208          s = f.getvalue()
    3209          self.assert_(len(s) <= len(s0))
    3210          gzfile = gzip.GzipFile(fileobj=BytesIO(s))
    3211          try:
    3212              s1 = gzfile.read()
    3213          finally:
    3214              gzfile.close()
    3215
    3216          f = BytesIO()
    3217          tree.write(f, compression=9)
    3218          s = f.getvalue()
    3219          self.assert_(len(s) <= len(s0))
    3220          gzfile = gzip.GzipFile(fileobj=BytesIO(s))
    3221          try:
    3222              s9 = gzfile.read()
    3223          finally:
    3224              gzfile.close()
    3225
    3226          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3227                            s0)
    3228          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3229                            s1)
    3230          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3231                            s9)
    3232
    3233 -    def test_write_file(self):
    3234          tree = self.parse(_bytes('<a><b/></a>'))
    3235          handle, filename = tempfile.mkstemp()
    3236          try:
    3237              tree.write(filename)
    3238              data = read_file(filename, 'rb')
    3239          finally:
    3240              os.close(handle)
    3241              os.remove(filename)
    3242          self.assertEquals(_bytes('<a><b/></a>'),
    3243                            data)
    3244
    3245 -    def test_write_file_gzip(self):
    3246          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3247          handle, filename = tempfile.mkstemp()
    3248          try:
    3249              tree.write(filename, compression=9)
    3250              f = gzip.open(filename, 'rb')
    3251              try:
    3252                  data = f.read()
    3253              finally:
    3254                  f.close()
    3255          finally:
    3256              os.close(handle)
    3257              os.remove(filename)
    3258          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3259                            data)
    3260
    3261 -    def test_write_file_gzip_parse(self):
    3262          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3263          handle, filename = tempfile.mkstemp()
    3264          try:
    3265              tree.write(filename, compression=9)
    3266              data = etree.tostring(etree.parse(filename))
    3267          finally:
    3268              os.close(handle)
    3269              os.remove(filename)
    3270          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3271                            data)
    3272
    3273 -    def test_write_file_gzipfile_parse(self):
    3274          tree = self.parse(_bytes('<a>'+'<b/>'*200+'</a>'))
    3275          handle, filename = tempfile.mkstemp()
    3276          try:
    3277              tree.write(filename, compression=9)
    3278              data = etree.tostring(etree.parse(
    3279                  gzip.GzipFile(filename)))
    3280          finally:
    3281              os.close(handle)
    3282              os.remove(filename)
    3283          self.assertEquals(_bytes('<a>'+'<b/>'*200+'</a>'),
    3284                            data)
    3285
    3286 -class ETreeErrorLogTest(HelperTestCase):
    3287      etree = etree
    3288
    3289 -    def test_parse_error_logging(self):
    3290          parse = self.etree.parse
    3291          f = BytesIO('<a><b></c></b></a>')
    3292          self.etree.clear_error_log()
    3293          try:
    3294              parse(f)
    3295              logs = None
    3296          except SyntaxError:
    3297              e = sys.exc_info()[1]
    3298              logs = e.error_log
    3299          f.close()
    3300          self.assert_([ log for log in logs
    3301                         if 'mismatch' in log.message ])
    3302          self.assert_([ log for log in logs
    3303                         if 'PARSER'   in log.domain_name])
    3304          self.assert_([ log for log in logs
    3305                         if 'ERR_TAG_NAME_MISMATCH' in log.type_name ])
    3306          self.assert_([ log for log in logs
    3307                         if 1 == log.line ])
    3308          self.assert_([ log for log in logs
    3309                         if 15 == log.column ])
    3310
    3311 -    def _test_python_error_logging(self):
    3312          """This can't really be tested as long as there isn't a way to
    3313          reset the logging setup ...
    3314          """
    3315          parse = self.etree.parse
    3316
    3317          messages = []
    3318          class Logger(self.etree.PyErrorLog):
    3319              def log(self, entry, message, *args):
    3320                  messages.append(message)
    3321
    3322          self.etree.use_global_python_log(Logger())
    3323          f = BytesIO('<a><b></c></b></a>')
    3324          try:
    3325              parse(f)
    3326          except SyntaxError:
    3327              pass
    3328          f.close()
    3329
    3330          self.assert_([ message for message in messages
    3331                         if 'mismatch' in message ])
    3332          self.assert_([ message for message in messages
    3333                         if ':PARSER:'   in message])
    3334          self.assert_([ message for message in messages
    3335                         if ':ERR_TAG_NAME_MISMATCH:' in message ])
    3336          self.assert_([ message for message in messages
    3337                         if ':1:15:' in message ])
    3338
    3339 -def test_suite():
    3340      suite = unittest.TestSuite()
    3341      suite.addTests([unittest.makeSuite(ETreeOnlyTestCase)])
    3342      suite.addTests([unittest.makeSuite(ETreeXIncludeTestCase)])
    3343      suite.addTests([unittest.makeSuite(ElementIncludeTestCase)])
    3344      suite.addTests([unittest.makeSuite(ETreeC14NTestCase)])
    3345      suite.addTests([unittest.makeSuite(ETreeWriteTestCase)])
    3346      suite.addTests([unittest.makeSuite(ETreeErrorLogTest)])
    3347      suite.addTests(
    3348          [make_doctest('../../../doc/tutorial.txt')])
    3349      suite.addTests(
    3350          [make_doctest('../../../doc/api.txt')])
    3351      suite.addTests(
    3352          [make_doctest('../../../doc/FAQ.txt')])
    3353      suite.addTests(
    3354          [make_doctest('../../../doc/parsing.txt')])
    3355      suite.addTests(
    3356          [make_doctest('../../../doc/resolvers.txt')])
    3357      return suite
    3358
    3359  if __name__ == '__main__':
    3360      print('to test use test.py %s' % __file__)
    3361