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