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):
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.assertEquals(root.FIND_ME, 47 TestElement.FIND_ME) 48 self.assertEquals(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.assertEquals("default element", root.FIND_ME) 74 self.assertEquals("default pi", root[0].FIND_ME) 75 self.assertEquals("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.assertEquals(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.assertEquals(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.assertEquals(root[0].FIND_ME, 131 TestElement1.FIND_ME) 132 self.assertFalse(hasattr(root[0][1], 'FIND_ME')) 133 self.assertEquals(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.assertEquals(root.FIND_ME, 152 TestElement.FIND_ME) 153 self.assertEquals(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.assertEquals(a.tag, "a") 184 self.assertEquals(root[0].tag, "a") 185 del a 186 self.assertEquals(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.assertEquals("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