Package lxml :: Package tests :: Module test_etree

[hide private]
[frames] | no frames]

# Source Code for Module lxml.tests.test_etree

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