1   
  2   
  3  """ 
  4  Tests specific to the Python based class lookup. 
  5  """ 
  6   
  7   
  8  import unittest, 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)  
 13   
 14  from common_imports import etree, StringIO, HelperTestCase, fileInTestDir 
 15  from common_imports import SillyFileLike, canonicalize, doctest, _bytes 
 16   
 17  from lxml.etree import PythonElementClassLookup 
 18   
 19  xml_str = _bytes('''\ 
 20  <obj:root xmlns:obj="objectified" xmlns:other="otherNS"> 
 21    <obj:c1 a1="A1" a2="A2" other:a3="A3"> 
 22      <obj:c2>0</obj:c2> 
 23      <obj:c2>1</obj:c2> 
 24      <obj:c2>2</obj:c2> 
 25      <other:c2>3</other:c2> 
 26      <c2>3</c2> 
 27    </obj:c1> 
 28  </obj:root>''') 
 29   
 30   
 46          self.parser.set_element_class_lookup( Lookup() ) 
 47   
 49          class LocalElement(etree.ElementBase): 
 50              pass 
  51          return LocalElement 
 52   
 55   
 56       
 57   
 59          el_class = self._buildElementClass() 
 60          el_class.i = 1 
 61          def lookup(*args): 
 62              if el_class.i == 1: 
 63                  el_class.i = 2 
 64              return el_class 
  65          self._setClassLookup(lookup) 
 66          root = self.XML(xml_str) 
 67          self.assertEqual(2, el_class.i) 
 68   
 70          el_class = self._buildElementClass() 
 71          el_class.EL = None 
 72          def lookup(doc, el): 
 73              if el_class.EL is None: 
 74                  el_class.EL = el 
 75              return el_class 
  76          self._setClassLookup(lookup) 
 77          root = self.XML(xml_str) 
 78          self.assertNotEqual(None, el_class.EL) 
 79          self.assertRaises(ReferenceError, el_class.EL.getchildren) 
 80   
 82          el_class = self._buildElementClass() 
 83          el_class.TAG = None 
 84          def lookup(doc, el): 
 85              if el_class.TAG is None: 
 86                  el_class.TAG = el.tag 
 87              return el_class 
  88          self._setClassLookup(lookup) 
 89          root = self.XML(xml_str) 
 90          self.assertNotEqual(None, root.TAG) 
 91          self.assertEqual(root.tag, root.TAG) 
 92   
 94          el_class = self._buildElementClass() 
 95          el_class.TEXT = None 
 96          def lookup(doc, el): 
 97              if el_class.TEXT is None: 
 98                  el_class.TEXT = el.text 
 99              return el_class 
 100          self._setClassLookup(lookup) 
101          root = self.XML(xml_str) 
102          self.assertNotEqual(None, root.TEXT) 
103          self.assertEqual(root.text, root.TEXT) 
104   
106          el_class = self._buildElementClass() 
107          el_class.TAIL = None 
108          def lookup(doc, el): 
109              if el_class.TAIL is None: 
110                  el_class.TAIL = el.tail 
111              return el_class 
 112          self._setClassLookup(lookup) 
113          root = self.XML(xml_str) 
114          self.assertEqual(root.tail, root.TAIL) 
115   
117          el_class = self._buildElementClass() 
118          el_class.ATTRIB = None 
119          def lookup(doc, el): 
120              if el_class.ATTRIB is None: 
121                  el_class.ATTRIB = el[0].attrib 
122              return el_class 
 123          self._setClassLookup(lookup) 
124          root = self.XML(xml_str) 
125          items1 = list(root[0].attrib.items()) 
126          items1.sort() 
127          items2 = list(root.ATTRIB.items()) 
128          items2.sort() 
129          self.assertEqual(items1, items2) 
130   
132          el_class = self._buildElementClass() 
133          el_class.PREFIX = None 
134          def lookup(doc, el): 
135              if el_class.PREFIX is None: 
136                  el_class.PREFIX = el.prefix 
137              return el_class 
 138          self._setClassLookup(lookup) 
139          root = self.XML(xml_str) 
140          self.assertEqual(root.prefix, root.PREFIX) 
141   
143          el_class = self._buildElementClass() 
144          el_class.LINE = None 
145          def lookup(doc, el): 
146              if el_class.LINE is None: 
147                  el_class.LINE = el.sourceline 
148              return el_class 
 149          self._setClassLookup(lookup) 
150          root = self.XML(xml_str) 
151          self.assertEqual(root.sourceline, root.LINE) 
152   
154          el_class = self._buildElementClass() 
155          el_class.CHILD_TAG = None 
156          def lookup(doc, el): 
157              el_class.CHILD_TAG = el[0].tag 
158              return el_class 
 159          self._setClassLookup(lookup) 
160          root = self.XML(xml_str) 
161          child_tag = root.CHILD_TAG 
162          self.assertNotEqual(None, child_tag) 
163          self.assertEqual(root[0].tag, child_tag) 
164   
166          el_class = self._buildElementClass() 
167          el_class.CHILD_TAG = None 
168          def lookup(doc, el): 
169              if el_class.CHILD_TAG is None: 
170                  el_class.CHILD_TAG = el[-1].tag 
171              return el_class 
 172          self._setClassLookup(lookup) 
173          root = self.XML(xml_str) 
174          child_tag = root.CHILD_TAG 
175          self.assertNotEqual(None, child_tag) 
176          self.assertEqual(root[-1].tag, child_tag) 
177   
179          el_class = self._buildElementClass() 
180          el_class.CHILD_TAGS = None 
181          def lookup(doc, el): 
182              if el_class.CHILD_TAGS is None: 
183                  el_class.CHILD_TAGS = [ c.tag for c in el[1:-1] ] 
184              return el_class 
 185          self._setClassLookup(lookup) 
186          root = self.XML(xml_str) 
187          child_tags = root.CHILD_TAGS 
188          self.assertNotEqual(None, child_tags) 
189          self.assertEqual([ c.tag for c in root[1:-1] ], 
190                            child_tags) 
191   
193          el_class = self._buildElementClass() 
194          el_class.LEN = None 
195          def lookup(doc, el): 
196              if el_class.LEN is None: 
197                  el_class.LEN = len(el) 
198              return el_class 
 199          self._setClassLookup(lookup) 
200          root = self.XML(xml_str) 
201          self.assertEqual(1, el_class.LEN) 
202   
204          el_class = self._buildElementClass() 
205          el_class.TRUE = None 
206          def lookup(doc, el): 
207              if el_class.TRUE is None: 
208                  el_class.TRUE = bool(el) 
209              return el_class 
 210          self._setClassLookup(lookup) 
211          root = self.XML(xml_str) 
212          self.assertTrue(el_class.TRUE) 
213   
215          el_class = self._buildElementClass() 
216          el_class.VAL = None 
217          def lookup(doc, el): 
218              if el_class.VAL is None: 
219                  el_class.VAL = el[0].get('a1') 
220              return el_class 
 221          self._setClassLookup(lookup) 
222          root = self.XML(xml_str) 
223          self.assertNotEqual(None, el_class.VAL) 
224          self.assertEqual(root[0].get('a1'), el_class.VAL) 
225   
227          el_class = self._buildElementClass() 
228          default = str(id(el_class)) 
229          el_class.VAL = None 
230          def lookup(doc, el): 
231              if el_class.VAL is None: 
232                  el_class.VAL = el[0].get('unknownattribute', default) 
233              return el_class 
 234          self._setClassLookup(lookup) 
235          root = self.XML(xml_str) 
236          self.assertEqual(default, el_class.VAL) 
237   
239          el_class = self._buildElementClass() 
240          el_class.CHILD_TAGS = None 
241          def lookup(doc, el): 
242              if el_class.CHILD_TAGS is None: 
243                  el_class.CHILD_TAGS = [ c.tag for c in el.getchildren() ] 
244              return el_class 
 245          self._setClassLookup(lookup) 
246          root = self.XML(xml_str) 
247          child_tags = root.CHILD_TAGS 
248          self.assertNotEqual(None, child_tags) 
249          self.assertEqual([ c.tag for c in root.getchildren() ], 
250                            child_tags) 
251   
253          el_class = self._buildElementClass() 
254          el_class.CHILD_TAGS = None 
255          def lookup(doc, el): 
256              if el_class.CHILD_TAGS is None: 
257                  el_class.CHILD_TAGS = [ c.tag for c in el ] 
258              return el_class 
 259          self._setClassLookup(lookup) 
260          root = self.XML(xml_str) 
261          child_tags = root.CHILD_TAGS 
262          self.assertNotEqual(None, child_tags) 
263          self.assertEqual([ c.tag for c in root.getchildren() ], 
264                            child_tags) 
265   
267          el_class = self._buildElementClass() 
268          el_class.CHILD_TAGS = None 
269          def lookup(doc, el): 
270              if el_class.CHILD_TAGS is None: 
271                  el_class.CHILD_TAGS = [ c.tag for c in el.iterchildren() ] 
272              return el_class 
 273          self._setClassLookup(lookup) 
274          root = self.XML(xml_str) 
275          child_tags = root.CHILD_TAGS 
276          self.assertNotEqual(None, child_tags) 
277          self.assertEqual([ c.tag for c in root.getchildren() ], 
278                            child_tags) 
279   
281          el_class = self._buildElementClass() 
282          el_class.CHILD_TAGS = None 
283          def lookup(doc, el): 
284              if not el_class.CHILD_TAGS: 
285                  el_class.CHILD_TAGS = [ 
286                      c.tag for c in el.iterchildren(tag='{objectified}c2') ] 
287              return el_class 
 288          self._setClassLookup(lookup) 
289   
290          root = self.XML(xml_str) 
291          child_tags = root.CHILD_TAGS 
292          self.assertNotEqual(None, child_tags) 
293          self.assertEqual([], child_tags) 
294   
295          c1 = root[0] 
296          child_tags = root.CHILD_TAGS 
297          self.assertNotEqual(None, child_tags) 
298          self.assertNotEqual([], child_tags) 
299          self.assertEqual( 
300              [ c.tag for c in root[0].iterchildren(tag='{objectified}c2') ], 
301              child_tags) 
302   
304          el_class = self._buildElementClass() 
305          el_class.PARENT = None 
306          def lookup(doc, el): 
307              if el_class.PARENT is None: 
308                  el_class.PARENT = el[0].getparent().tag 
309              return el_class 
 310          self._setClassLookup(lookup) 
311          root = self.XML(xml_str) 
312          self.assertEqual(root.tag, root.PARENT) 
313   
315          el_class = self._buildElementClass() 
316          el_class.NEXT = None 
317          def lookup(doc, el): 
318              if el_class.NEXT is None: 
319                  el_class.NEXT = el[0][1].getnext().tag 
320              return el_class 
 321          self._setClassLookup(lookup) 
322          root = self.XML(xml_str) 
323          self.assertNotEqual(None, el_class.NEXT) 
324          self.assertEqual(root[0][1].getnext().tag, el_class.NEXT) 
325   
327          el_class = self._buildElementClass() 
328          el_class.PREV = None 
329          def lookup(doc, el): 
330              if el_class.PREV is None: 
331                  el_class.PREV = el[0][1].getprevious().tag 
332              return el_class 
 333          self._setClassLookup(lookup) 
334          root = self.XML(xml_str) 
335          self.assertNotEqual(None, el_class.PREV) 
336          self.assertEqual(root[0][1].getprevious().tag, el_class.PREV) 
337   
341   
342          self._setClassLookup(return_none) 
343          el = self.XML('<a><!-- hello world --></a>') 
344          self.assertEqual(el[0].tag, self.etree.Comment) 
345          self.assertEqual(el[0].text, " hello world ") 
346   
347   
349      suite = unittest.TestSuite() 
350      suite.addTests([unittest.makeSuite(PyClassLookupTestCase)]) 
351      return suite 
 352   
353  if __name__ == '__main__': 
354      print('to test use test.py %s' % __file__) 
355