Files for 2.1b1 distribution.
[python/dscho.git] / Lib / test / test_minidom.py
blob5ff1beb90b6f43071e8006adfc35523696fd0588
1 # test for xml.dom.minidom
3 from xml.dom.minidom import parse, Node, Document, parseString
4 from xml.dom import HierarchyRequestErr
5 import xml.parsers.expat
7 import os.path
8 import sys
9 import traceback
10 from test_support import verbose
12 if __name__ == "__main__":
13 base = sys.argv[0]
14 else:
15 base = __file__
16 tstfile = os.path.join(os.path.dirname(base), "test.xml")
17 del base
19 def confirm(test, testname = "Test"):
20 if test:
21 print "Passed " + testname
22 else:
23 print "Failed " + testname
24 raise Exception
26 Node._debug = 1
28 def testParseFromFile():
29 from StringIO import StringIO
30 dom = parse(StringIO(open(tstfile).read()))
31 dom.unlink()
32 confirm(isinstance(dom,Document))
34 def testGetElementsByTagName():
35 dom = parse(tstfile)
36 confirm(dom.getElementsByTagName("LI") == \
37 dom.documentElement.getElementsByTagName("LI"))
38 dom.unlink()
40 def testInsertBefore():
41 dom = parseString("<doc><foo/></doc>")
42 root = dom.documentElement
43 elem = root.childNodes[0]
44 nelem = dom.createElement("element")
45 root.insertBefore(nelem, elem)
46 confirm(len(root.childNodes) == 2
47 and root.childNodes[0] is nelem
48 and root.childNodes[1] is elem
49 and root.firstChild is nelem
50 and root.lastChild is elem
51 and root.toxml() == "<doc><element/><foo/></doc>"
52 , "testInsertBefore -- node properly placed in tree")
53 nelem = dom.createElement("element")
54 root.insertBefore(nelem, None)
55 confirm(len(root.childNodes) == 3
56 and root.childNodes[1] is elem
57 and root.childNodes[2] is nelem
58 and root.lastChild is nelem
59 and nelem.previousSibling is elem
60 and root.toxml() == "<doc><element/><foo/><element/></doc>"
61 , "testInsertBefore -- node properly placed in tree")
62 nelem2 = dom.createElement("bar")
63 root.insertBefore(nelem2, nelem)
64 confirm(len(root.childNodes) == 4
65 and root.childNodes[2] is nelem2
66 and root.childNodes[3] is nelem
67 and nelem2.nextSibling is nelem
68 and nelem.previousSibling is nelem2
69 and root.toxml() == "<doc><element/><foo/><bar/><element/></doc>"
70 , "testInsertBefore -- node properly placed in tree")
71 dom.unlink()
73 def testAppendChild():
74 dom = parse(tstfile)
75 dom.documentElement.appendChild(dom.createComment(u"Hello"))
76 confirm(dom.documentElement.childNodes[-1].nodeName == "#comment")
77 confirm(dom.documentElement.childNodes[-1].data == "Hello")
78 dom.unlink()
80 def testLegalChildren():
81 dom = Document()
82 elem = dom.createElement('element')
83 text = dom.createTextNode('text')
85 try: dom.appendChild(text)
86 except HierarchyRequestErr: pass
87 else:
88 print "dom.appendChild didn't raise HierarchyRequestErr"
90 dom.appendChild(elem)
91 try: dom.insertBefore(text, elem)
92 except HierarchyRequestErr: pass
93 else:
94 print "dom.appendChild didn't raise HierarchyRequestErr"
96 try: dom.replaceChild(text, elem)
97 except HierarchyRequestErr: pass
98 else:
99 print "dom.appendChild didn't raise HierarchyRequestErr"
101 nodemap = elem.attributes
102 try: nodemap.setNamedItem(text)
103 except HierarchyRequestErr: pass
104 else:
105 print "NamedNodeMap.setNamedItem didn't raise HierarchyRequestErr"
107 try: nodemap.setNamedItemNS(text)
108 except HierarchyRequestErr: pass
109 else:
110 print "NamedNodeMap.setNamedItemNS didn't raise HierarchyRequestErr"
112 elem.appendChild(text)
113 dom.unlink()
115 def testNonZero():
116 dom = parse(tstfile)
117 confirm(dom)# should not be zero
118 dom.appendChild(dom.createComment("foo"))
119 confirm(not dom.childNodes[-1].childNodes)
120 dom.unlink()
122 def testUnlink():
123 dom = parse(tstfile)
124 dom.unlink()
126 def testElement():
127 dom = Document()
128 dom.appendChild(dom.createElement("abc"))
129 confirm(dom.documentElement)
130 dom.unlink()
132 def testAAA():
133 dom = parseString("<abc/>")
134 el = dom.documentElement
135 el.setAttribute("spam", "jam2")
136 confirm(el.toxml() == '<abc spam="jam2"/>', "testAAA")
137 dom.unlink()
139 def testAAB():
140 dom = parseString("<abc/>")
141 el = dom.documentElement
142 el.setAttribute("spam", "jam")
143 el.setAttribute("spam", "jam2")
144 confirm(el.toxml() == '<abc spam="jam2"/>', "testAAB")
145 dom.unlink()
147 def testAddAttr():
148 dom = Document()
149 child = dom.appendChild(dom.createElement("abc"))
151 child.setAttribute("def", "ghi")
152 confirm(child.getAttribute("def") == "ghi")
153 confirm(child.attributes["def"].value == "ghi")
155 child.setAttribute("jkl", "mno")
156 confirm(child.getAttribute("jkl") == "mno")
157 confirm(child.attributes["jkl"].value == "mno")
159 confirm(len(child.attributes) == 2)
161 child.setAttribute("def", "newval")
162 confirm(child.getAttribute("def") == "newval")
163 confirm(child.attributes["def"].value == "newval")
165 confirm(len(child.attributes) == 2)
166 dom.unlink()
168 def testDeleteAttr():
169 dom = Document()
170 child = dom.appendChild(dom.createElement("abc"))
172 confirm(len(child.attributes) == 0)
173 child.setAttribute("def", "ghi")
174 confirm(len(child.attributes) == 1)
175 del child.attributes["def"]
176 confirm(len(child.attributes) == 0)
177 dom.unlink()
179 def testRemoveAttr():
180 dom = Document()
181 child = dom.appendChild(dom.createElement("abc"))
183 child.setAttribute("def", "ghi")
184 confirm(len(child.attributes) == 1)
185 child.removeAttribute("def")
186 confirm(len(child.attributes) == 0)
188 dom.unlink()
190 def testRemoveAttrNS():
191 dom = Document()
192 child = dom.appendChild(
193 dom.createElementNS("http://www.python.org", "python:abc"))
194 child.setAttributeNS("http://www.w3.org", "xmlns:python",
195 "http://www.python.org")
196 child.setAttributeNS("http://www.python.org", "python:abcattr", "foo")
197 confirm(len(child.attributes) == 2)
198 child.removeAttributeNS("http://www.python.org", "abcattr")
199 confirm(len(child.attributes) == 1)
201 dom.unlink()
203 def testRemoveAttributeNode():
204 dom = Document()
205 child = dom.appendChild(dom.createElement("foo"))
206 child.setAttribute("spam", "jam")
207 confirm(len(child.attributes) == 1)
208 node = child.getAttributeNode("spam")
209 child.removeAttributeNode(node)
210 confirm(len(child.attributes) == 0)
212 dom.unlink()
214 def testChangeAttr():
215 dom = parseString("<abc/>")
216 el = dom.documentElement
217 el.setAttribute("spam", "jam")
218 confirm(len(el.attributes) == 1)
219 el.setAttribute("spam", "bam")
220 confirm(len(el.attributes) == 1)
221 el.attributes["spam"] = "ham"
222 confirm(len(el.attributes) == 1)
223 el.setAttribute("spam2", "bam")
224 confirm(len(el.attributes) == 2)
225 el.attributes[ "spam2"] = "bam2"
226 confirm(len(el.attributes) == 2)
227 dom.unlink()
229 def testGetAttrList():
230 pass
232 def testGetAttrValues(): pass
234 def testGetAttrLength(): pass
236 def testGetAttribute(): pass
238 def testGetAttributeNS(): pass
240 def testGetAttributeNode(): pass
242 def testGetElementsByTagNameNS(): pass
244 def testGetEmptyNodeListFromElementsByTagNameNS(): pass
246 def testElementReprAndStr():
247 dom = Document()
248 el = dom.appendChild(dom.createElement("abc"))
249 string1 = repr(el)
250 string2 = str(el)
251 confirm(string1 == string2)
252 dom.unlink()
254 # commented out until Fredrick's fix is checked in
255 def _testElementReprAndStrUnicode():
256 dom = Document()
257 el = dom.appendChild(dom.createElement(u"abc"))
258 string1 = repr(el)
259 string2 = str(el)
260 confirm(string1 == string2)
261 dom.unlink()
263 # commented out until Fredrick's fix is checked in
264 def _testElementReprAndStrUnicodeNS():
265 dom = Document()
266 el = dom.appendChild(
267 dom.createElementNS(u"http://www.slashdot.org", u"slash:abc"))
268 string1 = repr(el)
269 string2 = str(el)
270 confirm(string1 == string2)
271 confirm(string1.find("slash:abc") != -1)
272 dom.unlink()
273 confirm(len(Node.allnodes) == 0)
275 def testAttributeRepr():
276 dom = Document()
277 el = dom.appendChild(dom.createElement(u"abc"))
278 node = el.setAttribute("abc", "def")
279 confirm(str(node) == repr(node))
280 dom.unlink()
281 confirm(len(Node.allnodes) == 0)
283 def testTextNodeRepr(): pass
285 def testWriteXML():
286 str = '<?xml version="1.0" ?>\n<a b="c"/>'
287 dom = parseString(str)
288 domstr = dom.toxml()
289 dom.unlink()
290 confirm(str == domstr)
291 confirm(len(Node.allnodes) == 0)
293 def testProcessingInstruction(): pass
295 def testProcessingInstructionRepr(): pass
297 def testTextRepr(): pass
299 def testWriteText(): pass
301 def testDocumentElement(): pass
303 def testTooManyDocumentElements():
304 doc = parseString("<doc/>")
305 elem = doc.createElement("extra")
306 try:
307 doc.appendChild(elem)
308 except HierarchyRequestErr:
309 print "Caught expected exception when adding extra document element."
310 else:
311 print "Failed to catch expected exception when" \
312 " adding extra document element."
313 elem.unlink()
314 doc.unlink()
316 def testCreateElementNS(): pass
318 def testCreateAttributeNS(): pass
320 def testParse(): pass
322 def testParseString(): pass
324 def testComment(): pass
326 def testAttrListItem(): pass
328 def testAttrListItems(): pass
330 def testAttrListItemNS(): pass
332 def testAttrListKeys(): pass
334 def testAttrListKeysNS(): pass
336 def testAttrListValues(): pass
338 def testAttrListLength(): pass
340 def testAttrList__getitem__(): pass
342 def testAttrList__setitem__(): pass
344 def testSetAttrValueandNodeValue(): pass
346 def testParseElement(): pass
348 def testParseAttributes(): pass
350 def testParseElementNamespaces(): pass
352 def testParseAttributeNamespaces(): pass
354 def testParseProcessingInstructions(): pass
356 def testChildNodes(): pass
358 def testFirstChild(): pass
360 def testHasChildNodes(): pass
362 def testCloneElementShallow():
363 dom, clone = _setupCloneElement(0)
364 confirm(len(clone.childNodes) == 0
365 and clone.parentNode is None
366 and clone.toxml() == '<doc attr="value"/>'
367 , "testCloneElementShallow")
368 dom.unlink()
370 def testCloneElementDeep():
371 dom, clone = _setupCloneElement(1)
372 confirm(len(clone.childNodes) == 1
373 and clone.parentNode is None
374 and clone.toxml() == '<doc attr="value"><foo/></doc>'
375 , "testCloneElementDeep")
376 dom.unlink()
378 def _setupCloneElement(deep):
379 dom = parseString("<doc attr='value'><foo/></doc>")
380 root = dom.documentElement
381 clone = root.cloneNode(deep)
382 _testCloneElementCopiesAttributes(
383 root, clone, "testCloneElement" + (deep and "Deep" or "Shallow"))
384 # mutilate the original so shared data is detected
385 root.tagName = root.nodeName = "MODIFIED"
386 root.setAttribute("attr", "NEW VALUE")
387 root.setAttribute("added", "VALUE")
388 return dom, clone
390 def _testCloneElementCopiesAttributes(e1, e2, test):
391 attrs1 = e1.attributes
392 attrs2 = e2.attributes
393 keys1 = attrs1.keys()
394 keys2 = attrs2.keys()
395 keys1.sort()
396 keys2.sort()
397 confirm(keys1 == keys2, "clone of element has same attribute keys")
398 for i in range(len(keys1)):
399 a1 = attrs1.item(i)
400 a2 = attrs2.item(i)
401 confirm(a1 is not a2
402 and a1.value == a2.value
403 and a1.nodeValue == a2.nodeValue
404 and a1.namespaceURI == a2.namespaceURI
405 and a1.localName == a2.localName
406 , "clone of attribute node has proper attribute values")
407 confirm(a2.ownerElement is e2,
408 "clone of attribute node correctly owned")
411 def testCloneDocumentShallow(): pass
413 def testCloneDocumentDeep(): pass
415 def testCloneAttributeShallow(): pass
417 def testCloneAttributeDeep(): pass
419 def testClonePIShallow(): pass
421 def testClonePIDeep(): pass
423 def testNormalize():
424 doc = parseString("<doc/>")
425 root = doc.documentElement
426 root.appendChild(doc.createTextNode("first"))
427 root.appendChild(doc.createTextNode("second"))
428 confirm(len(root.childNodes) == 2, "testNormalize -- preparation")
429 doc.normalize()
430 confirm(len(root.childNodes) == 1
431 and root.firstChild is root.lastChild
432 and root.firstChild.data == "firstsecond"
433 , "testNormalize -- result")
434 doc.unlink()
436 doc = parseString("<doc/>")
437 root = doc.documentElement
438 root.appendChild(doc.createTextNode(""))
439 doc.normalize()
440 confirm(len(root.childNodes) == 0,
441 "testNormalize -- single empty node removed")
442 doc.unlink()
444 def testSiblings():
445 doc = parseString("<doc><?pi?>text?<elm/></doc>")
446 root = doc.documentElement
447 (pi, text, elm) = root.childNodes
449 confirm(pi.nextSibling is text and
450 pi.previousSibling is None and
451 text.nextSibling is elm and
452 text.previousSibling is pi and
453 elm.nextSibling is None and
454 elm.previousSibling is text, "testSiblings")
456 doc.unlink()
458 def testParents():
459 doc = parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
460 root = doc.documentElement
461 elm1 = root.childNodes[0]
462 (elm2a, elm2b) = elm1.childNodes
463 elm3 = elm2b.childNodes[0]
465 confirm(root.parentNode is doc and
466 elm1.parentNode is root and
467 elm2a.parentNode is elm1 and
468 elm2b.parentNode is elm1 and
469 elm3.parentNode is elm2b, "testParents")
471 doc.unlink()
473 def testSAX2DOM():
474 from xml.dom import pulldom
476 sax2dom = pulldom.SAX2DOM()
477 sax2dom.startDocument()
478 sax2dom.startElement("doc", {})
479 sax2dom.characters("text")
480 sax2dom.startElement("subelm", {})
481 sax2dom.characters("text")
482 sax2dom.endElement("subelm")
483 sax2dom.characters("text")
484 sax2dom.endElement("doc")
485 sax2dom.endDocument()
487 doc = sax2dom.document
488 root = doc.documentElement
489 (text1, elm1, text2) = root.childNodes
490 text3 = elm1.childNodes[0]
492 confirm(text1.previousSibling is None and
493 text1.nextSibling is elm1 and
494 elm1.previousSibling is text1 and
495 elm1.nextSibling is text2 and
496 text2.previousSibling is elm1 and
497 text2.nextSibling is None and
498 text3.previousSibling is None and
499 text3.nextSibling is None, "testSAX2DOM - siblings")
501 confirm(root.parentNode is doc and
502 text1.parentNode is root and
503 elm1.parentNode is root and
504 text2.parentNode is root and
505 text3.parentNode is elm1, "testSAX2DOM - parents")
507 doc.unlink()
509 # --- MAIN PROGRAM
511 names = globals().keys()
512 names.sort()
514 failed = []
516 for name in names:
517 if name.startswith("test"):
518 func = globals()[name]
519 try:
520 func()
521 print "Test Succeeded", name
522 confirm(len(Node.allnodes) == 0,
523 "assertion: len(Node.allnodes) == 0")
524 if len(Node.allnodes):
525 print "Garbage left over:"
526 if verbose:
527 print Node.allnodes.items()[0:10]
528 else:
529 # Don't print specific nodes if repeatable results
530 # are needed
531 print len(Node.allnodes)
532 Node.allnodes = {}
533 except:
534 failed.append(name)
535 print "Test Failed: ", name
536 sys.stdout.flush()
537 traceback.print_exception(*sys.exc_info())
538 print `sys.exc_info()[1]`
539 Node.allnodes = {}
541 if failed:
542 print "\n\n\n**** Check for failures in these tests:"
543 for name in failed:
544 print " " + name
545 print
546 else:
547 print "All tests succeeded"
549 Node.debug = None # Delete debug output collected in a StringIO object
550 Node._debug = 0 # And reset debug mode