Package lxml :: Package tests :: Module test_classlookup

[hide private]
[frames] | no frames]

# Source Code for Module lxml.tests.test_classlookup

      1  # -*- coding: utf-8 -*-
      2
      3  """
      4  Tests for different Element class lookup mechanisms.
      5  """
      6
      7
      8  import unittest, doctest, operator, os.path, sys
      9
     10  this_dir = os.path.dirname(__file__)
     11  if this_dir not in sys.path:
     12      sys.path.insert(0, this_dir) # needed for Py3
     13
     14  from common_imports import etree, HelperTestCase, SillyFileLike, fileInTestDir
     15  from common_imports import canonicalize, _bytes, _str, BytesIO, StringIO
     16
     17  xml_str = _bytes('''\
     18  <root xmlns="myNS" xmlns:other="otherNS">
     19    <c1 a1="A1" a2="A2" other:a3="A3">
     20      <c2 a1="C2">0</c2>
     21      <c2>1</c2>
     22      <other:c2>2</other:c2>
     23    </c1>
     24  </root>''')
     25
     26 -class ClassLookupTestCase(HelperTestCase):
     27      """Test cases for different Element class lookup mechanisms.
     28      """
     29      etree = etree
     30
     31 -    def tearDown(self):
     32          etree.set_element_class_lookup()
     33          super(ClassLookupTestCase, self).tearDown()
     34
     35 -    def test_namespace_lookup(self):
     36          class TestElement(etree.ElementBase):
     37              FIND_ME = "namespace class"
     38
     39          lookup = etree.ElementNamespaceClassLookup()
     40          etree.set_element_class_lookup(lookup)
     41
     42          ns = lookup.get_namespace("myNS")
     43          ns[None] = TestElement
     44
     45          root = etree.XML(xml_str)
     46          self.assertEqual(root.FIND_ME,
     47                            TestElement.FIND_ME)
     48          self.assertEqual(root[0].FIND_ME,
     49                            TestElement.FIND_ME)
     50          self.assertFalse(hasattr(root[0][-1], 'FIND_ME'))
     51
     52 -    def test_default_class_lookup(self):
     53          class TestElement(etree.ElementBase):
     54              FIND_ME = "default element"
     55          class TestComment(etree.CommentBase):
     56              FIND_ME = "default comment"
     57          class TestPI(etree.PIBase):
     58              FIND_ME = "default pi"
     59
     60          parser = etree.XMLParser()
     61
     62          lookup = etree.ElementDefaultClassLookup(
     63              element=TestElement, comment=TestComment, pi=TestPI)
     64          parser.set_element_class_lookup(lookup)
     65
     66          root = etree.XML(_bytes("""<?xml version='1.0'?>
     67          <root>
     68            <?myPI?>
     69            <!-- hi -->
     70          </root>
     71          """), parser)
     72
     73          self.assertEqual("default element", root.FIND_ME)
     74          self.assertEqual("default pi", root[0].FIND_ME)
     75          self.assertEqual("default comment", root[1].FIND_ME)
     76
     77 -    def test_attribute_based_lookup(self):
     78          class TestElement(etree.ElementBase):
     79              FIND_ME = "attribute_based"
     80
     81          class_dict = {"A1" : TestElement}
     82
     83          lookup = etree.AttributeBasedElementClassLookup(
     84              "a1", class_dict)
     85          etree.set_element_class_lookup(lookup)
     86
     87          root = etree.XML(xml_str)
     88          self.assertFalse(hasattr(root, 'FIND_ME'))
     89          self.assertEqual(root[0].FIND_ME,
     90                            TestElement.FIND_ME)
     91          self.assertFalse(hasattr(root[0][0], 'FIND_ME'))
     92
     93 -    def test_custom_lookup(self):
     94          class TestElement(etree.ElementBase):
     95              FIND_ME = "custom"
     96
     97          class MyLookup(etree.CustomElementClassLookup):
     98              def lookup(self, t, d, ns, name):
     99                  if name == 'c1':
    100                      return TestElement
    101
    102          etree.set_element_class_lookup( MyLookup() )
    103
    104          root = etree.XML(xml_str)
    105          self.assertFalse(hasattr(root, 'FIND_ME'))
    106          self.assertEqual(root[0].FIND_ME,
    107                            TestElement.FIND_ME)
    108          self.assertFalse(hasattr(root[0][1], 'FIND_ME'))
    109
    110 -    def test_custom_lookup_ns_fallback(self):
    111          class TestElement1(etree.ElementBase):
    112              FIND_ME = "custom"
    113
    114          class TestElement2(etree.ElementBase):
    115              FIND_ME = "nsclasses"
    116
    117          class MyLookup(etree.CustomElementClassLookup):
    118              def lookup(self, t, d, ns, name):
    119                  if name == 'c1':
    120                      return TestElement1
    121
    122          lookup = etree.ElementNamespaceClassLookup( MyLookup() )
    123          etree.set_element_class_lookup(lookup)
    124
    125          ns = lookup.get_namespace("otherNS")
    126          ns[None] = TestElement2
    127
    128          root = etree.XML(xml_str)
    129          self.assertFalse(hasattr(root, 'FIND_ME'))
    130          self.assertEqual(root[0].FIND_ME,
    131                            TestElement1.FIND_ME)
    132          self.assertFalse(hasattr(root[0][1], 'FIND_ME'))
    133          self.assertEqual(root[0][-1].FIND_ME,
    134                            TestElement2.FIND_ME)
    135
    136 -    def test_parser_based_lookup(self):
    137          class TestElement(etree.ElementBase):
    138              FIND_ME = "parser_based"
    139
    140          lookup = etree.ParserBasedElementClassLookup()
    141          etree.set_element_class_lookup(lookup)
    142
    143          class MyLookup(etree.CustomElementClassLookup):
    144              def lookup(self, t, d, ns, name):
    145                  return TestElement
    146
    147          parser = etree.XMLParser()
    148          parser.set_element_class_lookup( MyLookup() )
    149
    150          root = etree.parse(BytesIO(xml_str), parser).getroot()
    151          self.assertEqual(root.FIND_ME,
    152                            TestElement.FIND_ME)
    153          self.assertEqual(root[0].FIND_ME,
    154                            TestElement.FIND_ME)
    155
    156          root = etree.parse(BytesIO(xml_str)).getroot()
    157          self.assertFalse(hasattr(root, 'FIND_ME'))
    158          self.assertFalse(hasattr(root[0], 'FIND_ME'))
    159
    160 -    def test_class_lookup_reentry(self):
    161          XML = self.etree.XML
    162
    163          class TestElement(etree.ElementBase):
    164              FIND_ME = "here"
    165
    166          root = None
    167          class MyLookup(etree.CustomElementClassLookup):
    168              el = None
    169              def lookup(self, t, d, ns, name):
    170                  if root is not None: # not in the parser
    171                      if self.el is None and name == "a":
    172                          self.el = []
    173                          self.el.append(root.find(name))
    174                  return TestElement
    175
    176          parser = self.etree.XMLParser()
    177          parser.set_element_class_lookup(MyLookup())
    178
    179          root = XML(_bytes('<root><a>A</a><b xmlns="test">B</b></root>'),
    180                     parser)
    181
    182          a = root[0]
    183          self.assertEqual(a.tag, "a")
    184          self.assertEqual(root[0].tag, "a")
    185          del a
    186          self.assertEqual(root[0].tag, "a")
    187
    188 -    def test_lookup_without_fallback(self):
    189          class Lookup(etree.CustomElementClassLookup):
    190               def __init__(self):
    191                   # no super call here, so no fallback is set
    192                   pass
    193
    194               def lookup(self, node_type, document, namespace, name):
    195                   return Foo
    196
    197          class Foo(etree.ElementBase):
    198               def custom(self):
    199                   return "test"
    200
    201          parser = self.etree.XMLParser()
    202          parser.set_element_class_lookup( Lookup() )
    203
    204          root = etree.XML('<foo/>', parser)
    205
    206          self.assertEqual("test", root.custom())
    207
    208
    209 -def test_suite():
    210      suite = unittest.TestSuite()
    211      suite.addTests([unittest.makeSuite(ClassLookupTestCase)])
    212      return suite
    213
    214  if __name__ == '__main__':
    215      print('to test use test.py %s' % __file__)
    216