py-cvs-rel2_1 (Rev 1.2) merge
[python/dscho.git] / Lib / test / test_minidom.py
blobbdef6f5eebdd23784e9a563f6b074587b1e9f92c
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():
243 d="""<foo xmlns:minidom="http://pyxml.sf.net/minidom">
244 <minidom:myelem/>
245 </foo>"""
246 dom = parseString(d)
247 elem = dom.getElementsByTagNameNS("http://pyxml.sf.net/minidom","myelem")
248 confirm(len(elem) == 1)
249 dom.unlink()
251 def testGetEmptyNodeListFromElementsByTagNameNS(): pass
253 def testElementReprAndStr():
254 dom = Document()
255 el = dom.appendChild(dom.createElement("abc"))
256 string1 = repr(el)
257 string2 = str(el)
258 confirm(string1 == string2)
259 dom.unlink()
261 # commented out until Fredrick's fix is checked in
262 def _testElementReprAndStrUnicode():
263 dom = Document()
264 el = dom.appendChild(dom.createElement(u"abc"))
265 string1 = repr(el)
266 string2 = str(el)
267 confirm(string1 == string2)
268 dom.unlink()
270 # commented out until Fredrick's fix is checked in
271 def _testElementReprAndStrUnicodeNS():
272 dom = Document()
273 el = dom.appendChild(
274 dom.createElementNS(u"http://www.slashdot.org", u"slash:abc"))
275 string1 = repr(el)
276 string2 = str(el)
277 confirm(string1 == string2)
278 confirm(string1.find("slash:abc") != -1)
279 dom.unlink()
280 confirm(len(Node.allnodes) == 0)
282 def testAttributeRepr():
283 dom = Document()
284 el = dom.appendChild(dom.createElement(u"abc"))
285 node = el.setAttribute("abc", "def")
286 confirm(str(node) == repr(node))
287 dom.unlink()
288 confirm(len(Node.allnodes) == 0)
290 def testTextNodeRepr(): pass
292 def testWriteXML():
293 str = '<?xml version="1.0" ?>\n<a b="c"/>'
294 dom = parseString(str)
295 domstr = dom.toxml()
296 dom.unlink()
297 confirm(str == domstr)
298 confirm(len(Node.allnodes) == 0)
300 def testProcessingInstruction(): pass
302 def testProcessingInstructionRepr(): pass
304 def testTextRepr(): pass
306 def testWriteText(): pass
308 def testDocumentElement(): pass
310 def testTooManyDocumentElements():
311 doc = parseString("<doc/>")
312 elem = doc.createElement("extra")
313 try:
314 doc.appendChild(elem)
315 except HierarchyRequestErr:
316 print "Caught expected exception when adding extra document element."
317 else:
318 print "Failed to catch expected exception when" \
319 " adding extra document element."
320 elem.unlink()
321 doc.unlink()
323 def testCreateElementNS(): pass
325 def testCreateAttributeNS(): pass
327 def testParse(): pass
329 def testParseString(): pass
331 def testComment(): pass
333 def testAttrListItem(): pass
335 def testAttrListItems(): pass
337 def testAttrListItemNS(): pass
339 def testAttrListKeys(): pass
341 def testAttrListKeysNS(): pass
343 def testAttrListValues(): pass
345 def testAttrListLength(): pass
347 def testAttrList__getitem__(): pass
349 def testAttrList__setitem__(): pass
351 def testSetAttrValueandNodeValue(): pass
353 def testParseElement(): pass
355 def testParseAttributes(): pass
357 def testParseElementNamespaces(): pass
359 def testParseAttributeNamespaces(): pass
361 def testParseProcessingInstructions(): pass
363 def testChildNodes(): pass
365 def testFirstChild(): pass
367 def testHasChildNodes(): pass
369 def testCloneElementShallow():
370 dom, clone = _setupCloneElement(0)
371 confirm(len(clone.childNodes) == 0
372 and clone.parentNode is None
373 and clone.toxml() == '<doc attr="value"/>'
374 , "testCloneElementShallow")
375 dom.unlink()
377 def testCloneElementDeep():
378 dom, clone = _setupCloneElement(1)
379 confirm(len(clone.childNodes) == 1
380 and clone.parentNode is None
381 and clone.toxml() == '<doc attr="value"><foo/></doc>'
382 , "testCloneElementDeep")
383 dom.unlink()
385 def _setupCloneElement(deep):
386 dom = parseString("<doc attr='value'><foo/></doc>")
387 root = dom.documentElement
388 clone = root.cloneNode(deep)
389 _testCloneElementCopiesAttributes(
390 root, clone, "testCloneElement" + (deep and "Deep" or "Shallow"))
391 # mutilate the original so shared data is detected
392 root.tagName = root.nodeName = "MODIFIED"
393 root.setAttribute("attr", "NEW VALUE")
394 root.setAttribute("added", "VALUE")
395 return dom, clone
397 def _testCloneElementCopiesAttributes(e1, e2, test):
398 attrs1 = e1.attributes
399 attrs2 = e2.attributes
400 keys1 = attrs1.keys()
401 keys2 = attrs2.keys()
402 keys1.sort()
403 keys2.sort()
404 confirm(keys1 == keys2, "clone of element has same attribute keys")
405 for i in range(len(keys1)):
406 a1 = attrs1.item(i)
407 a2 = attrs2.item(i)
408 confirm(a1 is not a2
409 and a1.value == a2.value
410 and a1.nodeValue == a2.nodeValue
411 and a1.namespaceURI == a2.namespaceURI
412 and a1.localName == a2.localName
413 , "clone of attribute node has proper attribute values")
414 confirm(a2.ownerElement is e2,
415 "clone of attribute node correctly owned")
418 def testCloneDocumentShallow(): pass
420 def testCloneDocumentDeep(): pass
422 def testCloneAttributeShallow(): pass
424 def testCloneAttributeDeep(): pass
426 def testClonePIShallow(): pass
428 def testClonePIDeep(): pass
430 def testNormalize():
431 doc = parseString("<doc/>")
432 root = doc.documentElement
433 root.appendChild(doc.createTextNode("first"))
434 root.appendChild(doc.createTextNode("second"))
435 confirm(len(root.childNodes) == 2, "testNormalize -- preparation")
436 doc.normalize()
437 confirm(len(root.childNodes) == 1
438 and root.firstChild is root.lastChild
439 and root.firstChild.data == "firstsecond"
440 , "testNormalize -- result")
441 doc.unlink()
443 doc = parseString("<doc/>")
444 root = doc.documentElement
445 root.appendChild(doc.createTextNode(""))
446 doc.normalize()
447 confirm(len(root.childNodes) == 0,
448 "testNormalize -- single empty node removed")
449 doc.unlink()
451 def testSiblings():
452 doc = parseString("<doc><?pi?>text?<elm/></doc>")
453 root = doc.documentElement
454 (pi, text, elm) = root.childNodes
456 confirm(pi.nextSibling is text and
457 pi.previousSibling is None and
458 text.nextSibling is elm and
459 text.previousSibling is pi and
460 elm.nextSibling is None and
461 elm.previousSibling is text, "testSiblings")
463 doc.unlink()
465 def testParents():
466 doc = parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
467 root = doc.documentElement
468 elm1 = root.childNodes[0]
469 (elm2a, elm2b) = elm1.childNodes
470 elm3 = elm2b.childNodes[0]
472 confirm(root.parentNode is doc and
473 elm1.parentNode is root and
474 elm2a.parentNode is elm1 and
475 elm2b.parentNode is elm1 and
476 elm3.parentNode is elm2b, "testParents")
478 doc.unlink()
480 def testSAX2DOM():
481 from xml.dom import pulldom
483 sax2dom = pulldom.SAX2DOM()
484 sax2dom.startDocument()
485 sax2dom.startElement("doc", {})
486 sax2dom.characters("text")
487 sax2dom.startElement("subelm", {})
488 sax2dom.characters("text")
489 sax2dom.endElement("subelm")
490 sax2dom.characters("text")
491 sax2dom.endElement("doc")
492 sax2dom.endDocument()
494 doc = sax2dom.document
495 root = doc.documentElement
496 (text1, elm1, text2) = root.childNodes
497 text3 = elm1.childNodes[0]
499 confirm(text1.previousSibling is None and
500 text1.nextSibling is elm1 and
501 elm1.previousSibling is text1 and
502 elm1.nextSibling is text2 and
503 text2.previousSibling is elm1 and
504 text2.nextSibling is None and
505 text3.previousSibling is None and
506 text3.nextSibling is None, "testSAX2DOM - siblings")
508 confirm(root.parentNode is doc and
509 text1.parentNode is root and
510 elm1.parentNode is root and
511 text2.parentNode is root and
512 text3.parentNode is elm1, "testSAX2DOM - parents")
514 doc.unlink()
516 # --- MAIN PROGRAM
518 names = globals().keys()
519 names.sort()
521 failed = []
523 for name in names:
524 if name.startswith("test"):
525 func = globals()[name]
526 try:
527 func()
528 print "Test Succeeded", name
529 confirm(len(Node.allnodes) == 0,
530 "assertion: len(Node.allnodes) == 0")
531 if len(Node.allnodes):
532 print "Garbage left over:"
533 if verbose:
534 print Node.allnodes.items()[0:10]
535 else:
536 # Don't print specific nodes if repeatable results
537 # are needed
538 print len(Node.allnodes)
539 Node.allnodes = {}
540 except:
541 failed.append(name)
542 print "Test Failed: ", name
543 sys.stdout.flush()
544 traceback.print_exception(*sys.exc_info())
545 print `sys.exc_info()[1]`
546 Node.allnodes = {}
548 if failed:
549 print "\n\n\n**** Check for failures in these tests:"
550 for name in failed:
551 print " " + name
552 print
553 else:
554 print "All tests succeeded"
556 Node.debug = None # Delete debug output collected in a StringIO object
557 Node._debug = 0 # And reset debug mode