Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / src / nas,5.n2.os.2 / lib / python / lib / python2.4 / test / test_minidom.py
CommitLineData
86530b38
AT
1# test for xml.dom.minidom
2
3import os
4import sys
5import pickle
6import traceback
7from StringIO import StringIO
8from test.test_support import verbose
9
10import xml.dom
11import xml.dom.minidom
12import xml.parsers.expat
13
14from xml.dom.minidom import parse, Node, Document, parseString
15from xml.dom.minidom import getDOMImplementation
16
17
18if __name__ == "__main__":
19 base = sys.argv[0]
20else:
21 base = __file__
22tstfile = os.path.join(os.path.dirname(base), "test"+os.extsep+"xml")
23del base
24
25def confirm(test, testname = "Test"):
26 if not test:
27 print "Failed " + testname
28 raise Exception
29
30def testParseFromFile():
31 dom = parse(StringIO(open(tstfile).read()))
32 dom.unlink()
33 confirm(isinstance(dom,Document))
34
35def testGetElementsByTagName():
36 dom = parse(tstfile)
37 confirm(dom.getElementsByTagName("LI") == \
38 dom.documentElement.getElementsByTagName("LI"))
39 dom.unlink()
40
41def testInsertBefore():
42 dom = parseString("<doc><foo/></doc>")
43 root = dom.documentElement
44 elem = root.childNodes[0]
45 nelem = dom.createElement("element")
46 root.insertBefore(nelem, elem)
47 confirm(len(root.childNodes) == 2
48 and root.childNodes.length == 2
49 and root.childNodes[0] is nelem
50 and root.childNodes.item(0) is nelem
51 and root.childNodes[1] is elem
52 and root.childNodes.item(1) is elem
53 and root.firstChild is nelem
54 and root.lastChild is elem
55 and root.toxml() == "<doc><element/><foo/></doc>"
56 , "testInsertBefore -- node properly placed in tree")
57 nelem = dom.createElement("element")
58 root.insertBefore(nelem, None)
59 confirm(len(root.childNodes) == 3
60 and root.childNodes.length == 3
61 and root.childNodes[1] is elem
62 and root.childNodes.item(1) is elem
63 and root.childNodes[2] is nelem
64 and root.childNodes.item(2) is nelem
65 and root.lastChild is nelem
66 and nelem.previousSibling is elem
67 and root.toxml() == "<doc><element/><foo/><element/></doc>"
68 , "testInsertBefore -- node properly placed in tree")
69 nelem2 = dom.createElement("bar")
70 root.insertBefore(nelem2, nelem)
71 confirm(len(root.childNodes) == 4
72 and root.childNodes.length == 4
73 and root.childNodes[2] is nelem2
74 and root.childNodes.item(2) is nelem2
75 and root.childNodes[3] is nelem
76 and root.childNodes.item(3) is nelem
77 and nelem2.nextSibling is nelem
78 and nelem.previousSibling is nelem2
79 and root.toxml() == "<doc><element/><foo/><bar/><element/></doc>"
80 , "testInsertBefore -- node properly placed in tree")
81 dom.unlink()
82
83def _create_fragment_test_nodes():
84 dom = parseString("<doc/>")
85 orig = dom.createTextNode("original")
86 c1 = dom.createTextNode("foo")
87 c2 = dom.createTextNode("bar")
88 c3 = dom.createTextNode("bat")
89 dom.documentElement.appendChild(orig)
90 frag = dom.createDocumentFragment()
91 frag.appendChild(c1)
92 frag.appendChild(c2)
93 frag.appendChild(c3)
94 return dom, orig, c1, c2, c3, frag
95
96def testInsertBeforeFragment():
97 dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
98 dom.documentElement.insertBefore(frag, None)
99 confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
100 "insertBefore(<fragment>, None)")
101 frag.unlink()
102 dom.unlink()
103 #
104 dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
105 dom.documentElement.insertBefore(frag, orig)
106 confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3, orig),
107 "insertBefore(<fragment>, orig)")
108 frag.unlink()
109 dom.unlink()
110
111def testAppendChild():
112 dom = parse(tstfile)
113 dom.documentElement.appendChild(dom.createComment(u"Hello"))
114 confirm(dom.documentElement.childNodes[-1].nodeName == "#comment")
115 confirm(dom.documentElement.childNodes[-1].data == "Hello")
116 dom.unlink()
117
118def testAppendChildFragment():
119 dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
120 dom.documentElement.appendChild(frag)
121 confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
122 "appendChild(<fragment>)")
123 frag.unlink()
124 dom.unlink()
125
126def testReplaceChildFragment():
127 dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
128 dom.documentElement.replaceChild(frag, orig)
129 orig.unlink()
130 confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3),
131 "replaceChild(<fragment>)")
132 frag.unlink()
133 dom.unlink()
134
135def testLegalChildren():
136 dom = Document()
137 elem = dom.createElement('element')
138 text = dom.createTextNode('text')
139
140 try: dom.appendChild(text)
141 except xml.dom.HierarchyRequestErr: pass
142 else:
143 print "dom.appendChild didn't raise HierarchyRequestErr"
144
145 dom.appendChild(elem)
146 try: dom.insertBefore(text, elem)
147 except xml.dom.HierarchyRequestErr: pass
148 else:
149 print "dom.appendChild didn't raise HierarchyRequestErr"
150
151 try: dom.replaceChild(text, elem)
152 except xml.dom.HierarchyRequestErr: pass
153 else:
154 print "dom.appendChild didn't raise HierarchyRequestErr"
155
156 nodemap = elem.attributes
157 try: nodemap.setNamedItem(text)
158 except xml.dom.HierarchyRequestErr: pass
159 else:
160 print "NamedNodeMap.setNamedItem didn't raise HierarchyRequestErr"
161
162 try: nodemap.setNamedItemNS(text)
163 except xml.dom.HierarchyRequestErr: pass
164 else:
165 print "NamedNodeMap.setNamedItemNS didn't raise HierarchyRequestErr"
166
167 elem.appendChild(text)
168 dom.unlink()
169
170def testNamedNodeMapSetItem():
171 dom = Document()
172 elem = dom.createElement('element')
173 attrs = elem.attributes
174 attrs["foo"] = "bar"
175 a = attrs.item(0)
176 confirm(a.ownerDocument is dom,
177 "NamedNodeMap.__setitem__() sets ownerDocument")
178 confirm(a.ownerElement is elem,
179 "NamedNodeMap.__setitem__() sets ownerElement")
180 confirm(a.value == "bar",
181 "NamedNodeMap.__setitem__() sets value")
182 confirm(a.nodeValue == "bar",
183 "NamedNodeMap.__setitem__() sets nodeValue")
184 elem.unlink()
185 dom.unlink()
186
187def testNonZero():
188 dom = parse(tstfile)
189 confirm(dom)# should not be zero
190 dom.appendChild(dom.createComment("foo"))
191 confirm(not dom.childNodes[-1].childNodes)
192 dom.unlink()
193
194def testUnlink():
195 dom = parse(tstfile)
196 dom.unlink()
197
198def testElement():
199 dom = Document()
200 dom.appendChild(dom.createElement("abc"))
201 confirm(dom.documentElement)
202 dom.unlink()
203
204def testAAA():
205 dom = parseString("<abc/>")
206 el = dom.documentElement
207 el.setAttribute("spam", "jam2")
208 confirm(el.toxml() == '<abc spam="jam2"/>', "testAAA")
209 a = el.getAttributeNode("spam")
210 confirm(a.ownerDocument is dom,
211 "setAttribute() sets ownerDocument")
212 confirm(a.ownerElement is dom.documentElement,
213 "setAttribute() sets ownerElement")
214 dom.unlink()
215
216def testAAB():
217 dom = parseString("<abc/>")
218 el = dom.documentElement
219 el.setAttribute("spam", "jam")
220 el.setAttribute("spam", "jam2")
221 confirm(el.toxml() == '<abc spam="jam2"/>', "testAAB")
222 dom.unlink()
223
224def testAddAttr():
225 dom = Document()
226 child = dom.appendChild(dom.createElement("abc"))
227
228 child.setAttribute("def", "ghi")
229 confirm(child.getAttribute("def") == "ghi")
230 confirm(child.attributes["def"].value == "ghi")
231
232 child.setAttribute("jkl", "mno")
233 confirm(child.getAttribute("jkl") == "mno")
234 confirm(child.attributes["jkl"].value == "mno")
235
236 confirm(len(child.attributes) == 2)
237
238 child.setAttribute("def", "newval")
239 confirm(child.getAttribute("def") == "newval")
240 confirm(child.attributes["def"].value == "newval")
241
242 confirm(len(child.attributes) == 2)
243 dom.unlink()
244
245def testDeleteAttr():
246 dom = Document()
247 child = dom.appendChild(dom.createElement("abc"))
248
249 confirm(len(child.attributes) == 0)
250 child.setAttribute("def", "ghi")
251 confirm(len(child.attributes) == 1)
252 del child.attributes["def"]
253 confirm(len(child.attributes) == 0)
254 dom.unlink()
255
256def testRemoveAttr():
257 dom = Document()
258 child = dom.appendChild(dom.createElement("abc"))
259
260 child.setAttribute("def", "ghi")
261 confirm(len(child.attributes) == 1)
262 child.removeAttribute("def")
263 confirm(len(child.attributes) == 0)
264
265 dom.unlink()
266
267def testRemoveAttrNS():
268 dom = Document()
269 child = dom.appendChild(
270 dom.createElementNS("http://www.python.org", "python:abc"))
271 child.setAttributeNS("http://www.w3.org", "xmlns:python",
272 "http://www.python.org")
273 child.setAttributeNS("http://www.python.org", "python:abcattr", "foo")
274 confirm(len(child.attributes) == 2)
275 child.removeAttributeNS("http://www.python.org", "abcattr")
276 confirm(len(child.attributes) == 1)
277
278 dom.unlink()
279
280def testRemoveAttributeNode():
281 dom = Document()
282 child = dom.appendChild(dom.createElement("foo"))
283 child.setAttribute("spam", "jam")
284 confirm(len(child.attributes) == 1)
285 node = child.getAttributeNode("spam")
286 child.removeAttributeNode(node)
287 confirm(len(child.attributes) == 0
288 and child.getAttributeNode("spam") is None)
289
290 dom.unlink()
291
292def testChangeAttr():
293 dom = parseString("<abc/>")
294 el = dom.documentElement
295 el.setAttribute("spam", "jam")
296 confirm(len(el.attributes) == 1)
297 el.setAttribute("spam", "bam")
298 # Set this attribute to be an ID and make sure that doesn't change
299 # when changing the value:
300 el.setIdAttribute("spam")
301 confirm(len(el.attributes) == 1
302 and el.attributes["spam"].value == "bam"
303 and el.attributes["spam"].nodeValue == "bam"
304 and el.getAttribute("spam") == "bam"
305 and el.getAttributeNode("spam").isId)
306 el.attributes["spam"] = "ham"
307 confirm(len(el.attributes) == 1
308 and el.attributes["spam"].value == "ham"
309 and el.attributes["spam"].nodeValue == "ham"
310 and el.getAttribute("spam") == "ham"
311 and el.attributes["spam"].isId)
312 el.setAttribute("spam2", "bam")
313 confirm(len(el.attributes) == 2
314 and el.attributes["spam"].value == "ham"
315 and el.attributes["spam"].nodeValue == "ham"
316 and el.getAttribute("spam") == "ham"
317 and el.attributes["spam2"].value == "bam"
318 and el.attributes["spam2"].nodeValue == "bam"
319 and el.getAttribute("spam2") == "bam")
320 el.attributes["spam2"] = "bam2"
321 confirm(len(el.attributes) == 2
322 and el.attributes["spam"].value == "ham"
323 and el.attributes["spam"].nodeValue == "ham"
324 and el.getAttribute("spam") == "ham"
325 and el.attributes["spam2"].value == "bam2"
326 and el.attributes["spam2"].nodeValue == "bam2"
327 and el.getAttribute("spam2") == "bam2")
328 dom.unlink()
329
330def testGetAttrList():
331 pass
332
333def testGetAttrValues(): pass
334
335def testGetAttrLength(): pass
336
337def testGetAttribute(): pass
338
339def testGetAttributeNS(): pass
340
341def testGetAttributeNode(): pass
342
343def testGetElementsByTagNameNS():
344 d="""<foo xmlns:minidom='http://pyxml.sf.net/minidom'>
345 <minidom:myelem/>
346 </foo>"""
347 dom = parseString(d)
348 elems = dom.getElementsByTagNameNS("http://pyxml.sf.net/minidom", "myelem")
349 confirm(len(elems) == 1
350 and elems[0].namespaceURI == "http://pyxml.sf.net/minidom"
351 and elems[0].localName == "myelem"
352 and elems[0].prefix == "minidom"
353 and elems[0].tagName == "minidom:myelem"
354 and elems[0].nodeName == "minidom:myelem")
355 dom.unlink()
356
357def get_empty_nodelist_from_elements_by_tagName_ns_helper(doc, nsuri, lname):
358 nodelist = doc.getElementsByTagNameNS(nsuri, lname)
359 confirm(len(nodelist) == 0)
360
361def testGetEmptyNodeListFromElementsByTagNameNS():
362 doc = parseString('<doc/>')
363 get_empty_nodelist_from_elements_by_tagName_ns_helper(
364 doc, 'http://xml.python.org/namespaces/a', 'localname')
365 get_empty_nodelist_from_elements_by_tagName_ns_helper(
366 doc, '*', 'splat')
367 get_empty_nodelist_from_elements_by_tagName_ns_helper(
368 doc, 'http://xml.python.org/namespaces/a', '*')
369
370 doc = parseString('<doc xmlns="http://xml.python.org/splat"><e/></doc>')
371 get_empty_nodelist_from_elements_by_tagName_ns_helper(
372 doc, "http://xml.python.org/splat", "not-there")
373 get_empty_nodelist_from_elements_by_tagName_ns_helper(
374 doc, "*", "not-there")
375 get_empty_nodelist_from_elements_by_tagName_ns_helper(
376 doc, "http://somewhere.else.net/not-there", "e")
377
378def testElementReprAndStr():
379 dom = Document()
380 el = dom.appendChild(dom.createElement("abc"))
381 string1 = repr(el)
382 string2 = str(el)
383 confirm(string1 == string2)
384 dom.unlink()
385
386# commented out until Fredrick's fix is checked in
387def _testElementReprAndStrUnicode():
388 dom = Document()
389 el = dom.appendChild(dom.createElement(u"abc"))
390 string1 = repr(el)
391 string2 = str(el)
392 confirm(string1 == string2)
393 dom.unlink()
394
395# commented out until Fredrick's fix is checked in
396def _testElementReprAndStrUnicodeNS():
397 dom = Document()
398 el = dom.appendChild(
399 dom.createElementNS(u"http://www.slashdot.org", u"slash:abc"))
400 string1 = repr(el)
401 string2 = str(el)
402 confirm(string1 == string2)
403 confirm(string1.find("slash:abc") != -1)
404 dom.unlink()
405
406def testAttributeRepr():
407 dom = Document()
408 el = dom.appendChild(dom.createElement(u"abc"))
409 node = el.setAttribute("abc", "def")
410 confirm(str(node) == repr(node))
411 dom.unlink()
412
413def testTextNodeRepr(): pass
414
415def testWriteXML():
416 str = '<?xml version="1.0" ?><a b="c"/>'
417 dom = parseString(str)
418 domstr = dom.toxml()
419 dom.unlink()
420 confirm(str == domstr)
421
422def testAltNewline():
423 str = '<?xml version="1.0" ?>\n<a b="c"/>\n'
424 dom = parseString(str)
425 domstr = dom.toprettyxml(newl="\r\n")
426 dom.unlink()
427 confirm(domstr == str.replace("\n", "\r\n"))
428
429def testProcessingInstruction():
430 dom = parseString('<e><?mypi \t\n data \t\n ?></e>')
431 pi = dom.documentElement.firstChild
432 confirm(pi.target == "mypi"
433 and pi.data == "data \t\n "
434 and pi.nodeName == "mypi"
435 and pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE
436 and pi.attributes is None
437 and not pi.hasChildNodes()
438 and len(pi.childNodes) == 0
439 and pi.firstChild is None
440 and pi.lastChild is None
441 and pi.localName is None
442 and pi.namespaceURI == xml.dom.EMPTY_NAMESPACE)
443
444def testProcessingInstructionRepr(): pass
445
446def testTextRepr(): pass
447
448def testWriteText(): pass
449
450def testDocumentElement(): pass
451
452def testTooManyDocumentElements():
453 doc = parseString("<doc/>")
454 elem = doc.createElement("extra")
455 try:
456 doc.appendChild(elem)
457 except xml.dom.HierarchyRequestErr:
458 pass
459 else:
460 print "Failed to catch expected exception when" \
461 " adding extra document element."
462 elem.unlink()
463 doc.unlink()
464
465def testCreateElementNS(): pass
466
467def testCreateAttributeNS(): pass
468
469def testParse(): pass
470
471def testParseString(): pass
472
473def testComment(): pass
474
475def testAttrListItem(): pass
476
477def testAttrListItems(): pass
478
479def testAttrListItemNS(): pass
480
481def testAttrListKeys(): pass
482
483def testAttrListKeysNS(): pass
484
485def testRemoveNamedItem():
486 doc = parseString("<doc a=''/>")
487 e = doc.documentElement
488 attrs = e.attributes
489 a1 = e.getAttributeNode("a")
490 a2 = attrs.removeNamedItem("a")
491 confirm(a1.isSameNode(a2))
492 try:
493 attrs.removeNamedItem("a")
494 except xml.dom.NotFoundErr:
495 pass
496
497def testRemoveNamedItemNS():
498 doc = parseString("<doc xmlns:a='http://xml.python.org/' a:b=''/>")
499 e = doc.documentElement
500 attrs = e.attributes
501 a1 = e.getAttributeNodeNS("http://xml.python.org/", "b")
502 a2 = attrs.removeNamedItemNS("http://xml.python.org/", "b")
503 confirm(a1.isSameNode(a2))
504 try:
505 attrs.removeNamedItemNS("http://xml.python.org/", "b")
506 except xml.dom.NotFoundErr:
507 pass
508
509def testAttrListValues(): pass
510
511def testAttrListLength(): pass
512
513def testAttrList__getitem__(): pass
514
515def testAttrList__setitem__(): pass
516
517def testSetAttrValueandNodeValue(): pass
518
519def testParseElement(): pass
520
521def testParseAttributes(): pass
522
523def testParseElementNamespaces(): pass
524
525def testParseAttributeNamespaces(): pass
526
527def testParseProcessingInstructions(): pass
528
529def testChildNodes(): pass
530
531def testFirstChild(): pass
532
533def testHasChildNodes(): pass
534
535def testCloneElementShallow():
536 dom, clone = _setupCloneElement(0)
537 confirm(len(clone.childNodes) == 0
538 and clone.childNodes.length == 0
539 and clone.parentNode is None
540 and clone.toxml() == '<doc attr="value"/>'
541 , "testCloneElementShallow")
542 dom.unlink()
543
544def testCloneElementDeep():
545 dom, clone = _setupCloneElement(1)
546 confirm(len(clone.childNodes) == 1
547 and clone.childNodes.length == 1
548 and clone.parentNode is None
549 and clone.toxml() == '<doc attr="value"><foo/></doc>'
550 , "testCloneElementDeep")
551 dom.unlink()
552
553def _setupCloneElement(deep):
554 dom = parseString("<doc attr='value'><foo/></doc>")
555 root = dom.documentElement
556 clone = root.cloneNode(deep)
557 _testCloneElementCopiesAttributes(
558 root, clone, "testCloneElement" + (deep and "Deep" or "Shallow"))
559 # mutilate the original so shared data is detected
560 root.tagName = root.nodeName = "MODIFIED"
561 root.setAttribute("attr", "NEW VALUE")
562 root.setAttribute("added", "VALUE")
563 return dom, clone
564
565def _testCloneElementCopiesAttributes(e1, e2, test):
566 attrs1 = e1.attributes
567 attrs2 = e2.attributes
568 keys1 = attrs1.keys()
569 keys2 = attrs2.keys()
570 keys1.sort()
571 keys2.sort()
572 confirm(keys1 == keys2, "clone of element has same attribute keys")
573 for i in range(len(keys1)):
574 a1 = attrs1.item(i)
575 a2 = attrs2.item(i)
576 confirm(a1 is not a2
577 and a1.value == a2.value
578 and a1.nodeValue == a2.nodeValue
579 and a1.namespaceURI == a2.namespaceURI
580 and a1.localName == a2.localName
581 , "clone of attribute node has proper attribute values")
582 confirm(a2.ownerElement is e2,
583 "clone of attribute node correctly owned")
584
585def testCloneDocumentShallow():
586 doc = parseString("<?xml version='1.0'?>\n"
587 "<!-- comment -->"
588 "<!DOCTYPE doc [\n"
589 "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
590 "]>\n"
591 "<doc attr='value'/>")
592 doc2 = doc.cloneNode(0)
593 confirm(doc2 is None,
594 "testCloneDocumentShallow:"
595 " shallow cloning of documents makes no sense!")
596
597def testCloneDocumentDeep():
598 doc = parseString("<?xml version='1.0'?>\n"
599 "<!-- comment -->"
600 "<!DOCTYPE doc [\n"
601 "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
602 "]>\n"
603 "<doc attr='value'/>")
604 doc2 = doc.cloneNode(1)
605 confirm(not (doc.isSameNode(doc2) or doc2.isSameNode(doc)),
606 "testCloneDocumentDeep: document objects not distinct")
607 confirm(len(doc.childNodes) == len(doc2.childNodes),
608 "testCloneDocumentDeep: wrong number of Document children")
609 confirm(doc2.documentElement.nodeType == Node.ELEMENT_NODE,
610 "testCloneDocumentDeep: documentElement not an ELEMENT_NODE")
611 confirm(doc2.documentElement.ownerDocument.isSameNode(doc2),
612 "testCloneDocumentDeep: documentElement owner is not new document")
613 confirm(not doc.documentElement.isSameNode(doc2.documentElement),
614 "testCloneDocumentDeep: documentElement should not be shared")
615 if doc.doctype is not None:
616 # check the doctype iff the original DOM maintained it
617 confirm(doc2.doctype.nodeType == Node.DOCUMENT_TYPE_NODE,
618 "testCloneDocumentDeep: doctype not a DOCUMENT_TYPE_NODE")
619 confirm(doc2.doctype.ownerDocument.isSameNode(doc2))
620 confirm(not doc.doctype.isSameNode(doc2.doctype))
621
622def testCloneDocumentTypeDeepOk():
623 doctype = create_nonempty_doctype()
624 clone = doctype.cloneNode(1)
625 confirm(clone is not None
626 and clone.nodeName == doctype.nodeName
627 and clone.name == doctype.name
628 and clone.publicId == doctype.publicId
629 and clone.systemId == doctype.systemId
630 and len(clone.entities) == len(doctype.entities)
631 and clone.entities.item(len(clone.entities)) is None
632 and len(clone.notations) == len(doctype.notations)
633 and clone.notations.item(len(clone.notations)) is None
634 and len(clone.childNodes) == 0)
635 for i in range(len(doctype.entities)):
636 se = doctype.entities.item(i)
637 ce = clone.entities.item(i)
638 confirm((not se.isSameNode(ce))
639 and (not ce.isSameNode(se))
640 and ce.nodeName == se.nodeName
641 and ce.notationName == se.notationName
642 and ce.publicId == se.publicId
643 and ce.systemId == se.systemId
644 and ce.encoding == se.encoding
645 and ce.actualEncoding == se.actualEncoding
646 and ce.version == se.version)
647 for i in range(len(doctype.notations)):
648 sn = doctype.notations.item(i)
649 cn = clone.notations.item(i)
650 confirm((not sn.isSameNode(cn))
651 and (not cn.isSameNode(sn))
652 and cn.nodeName == sn.nodeName
653 and cn.publicId == sn.publicId
654 and cn.systemId == sn.systemId)
655
656def testCloneDocumentTypeDeepNotOk():
657 doc = create_doc_with_doctype()
658 clone = doc.doctype.cloneNode(1)
659 confirm(clone is None, "testCloneDocumentTypeDeepNotOk")
660
661def testCloneDocumentTypeShallowOk():
662 doctype = create_nonempty_doctype()
663 clone = doctype.cloneNode(0)
664 confirm(clone is not None
665 and clone.nodeName == doctype.nodeName
666 and clone.name == doctype.name
667 and clone.publicId == doctype.publicId
668 and clone.systemId == doctype.systemId
669 and len(clone.entities) == 0
670 and clone.entities.item(0) is None
671 and len(clone.notations) == 0
672 and clone.notations.item(0) is None
673 and len(clone.childNodes) == 0)
674
675def testCloneDocumentTypeShallowNotOk():
676 doc = create_doc_with_doctype()
677 clone = doc.doctype.cloneNode(0)
678 confirm(clone is None, "testCloneDocumentTypeShallowNotOk")
679
680def check_import_document(deep, testName):
681 doc1 = parseString("<doc/>")
682 doc2 = parseString("<doc/>")
683 try:
684 doc1.importNode(doc2, deep)
685 except xml.dom.NotSupportedErr:
686 pass
687 else:
688 raise Exception(testName +
689 ": expected NotSupportedErr when importing a document")
690
691def testImportDocumentShallow():
692 check_import_document(0, "testImportDocumentShallow")
693
694def testImportDocumentDeep():
695 check_import_document(1, "testImportDocumentDeep")
696
697# The tests of DocumentType importing use these helpers to construct
698# the documents to work with, since not all DOM builders actually
699# create the DocumentType nodes.
700
701def create_doc_without_doctype(doctype=None):
702 return getDOMImplementation().createDocument(None, "doc", doctype)
703
704def create_nonempty_doctype():
705 doctype = getDOMImplementation().createDocumentType("doc", None, None)
706 doctype.entities._seq = []
707 doctype.notations._seq = []
708 notation = xml.dom.minidom.Notation("my-notation", None,
709 "http://xml.python.org/notations/my")
710 doctype.notations._seq.append(notation)
711 entity = xml.dom.minidom.Entity("my-entity", None,
712 "http://xml.python.org/entities/my",
713 "my-notation")
714 entity.version = "1.0"
715 entity.encoding = "utf-8"
716 entity.actualEncoding = "us-ascii"
717 doctype.entities._seq.append(entity)
718 return doctype
719
720def create_doc_with_doctype():
721 doctype = create_nonempty_doctype()
722 doc = create_doc_without_doctype(doctype)
723 doctype.entities.item(0).ownerDocument = doc
724 doctype.notations.item(0).ownerDocument = doc
725 return doc
726
727def testImportDocumentTypeShallow():
728 src = create_doc_with_doctype()
729 target = create_doc_without_doctype()
730 try:
731 imported = target.importNode(src.doctype, 0)
732 except xml.dom.NotSupportedErr:
733 pass
734 else:
735 raise Exception(
736 "testImportDocumentTypeShallow: expected NotSupportedErr")
737
738def testImportDocumentTypeDeep():
739 src = create_doc_with_doctype()
740 target = create_doc_without_doctype()
741 try:
742 imported = target.importNode(src.doctype, 1)
743 except xml.dom.NotSupportedErr:
744 pass
745 else:
746 raise Exception(
747 "testImportDocumentTypeDeep: expected NotSupportedErr")
748
749# Testing attribute clones uses a helper, and should always be deep,
750# even if the argument to cloneNode is false.
751def check_clone_attribute(deep, testName):
752 doc = parseString("<doc attr='value'/>")
753 attr = doc.documentElement.getAttributeNode("attr")
754 assert attr is not None
755 clone = attr.cloneNode(deep)
756 confirm(not clone.isSameNode(attr))
757 confirm(not attr.isSameNode(clone))
758 confirm(clone.ownerElement is None,
759 testName + ": ownerElement should be None")
760 confirm(clone.ownerDocument.isSameNode(attr.ownerDocument),
761 testName + ": ownerDocument does not match")
762 confirm(clone.specified,
763 testName + ": cloned attribute must have specified == True")
764
765def testCloneAttributeShallow():
766 check_clone_attribute(0, "testCloneAttributeShallow")
767
768def testCloneAttributeDeep():
769 check_clone_attribute(1, "testCloneAttributeDeep")
770
771def check_clone_pi(deep, testName):
772 doc = parseString("<?target data?><doc/>")
773 pi = doc.firstChild
774 assert pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE
775 clone = pi.cloneNode(deep)
776 confirm(clone.target == pi.target
777 and clone.data == pi.data)
778
779def testClonePIShallow():
780 check_clone_pi(0, "testClonePIShallow")
781
782def testClonePIDeep():
783 check_clone_pi(1, "testClonePIDeep")
784
785def testNormalize():
786 doc = parseString("<doc/>")
787 root = doc.documentElement
788 root.appendChild(doc.createTextNode("first"))
789 root.appendChild(doc.createTextNode("second"))
790 confirm(len(root.childNodes) == 2
791 and root.childNodes.length == 2, "testNormalize -- preparation")
792 doc.normalize()
793 confirm(len(root.childNodes) == 1
794 and root.childNodes.length == 1
795 and root.firstChild is root.lastChild
796 and root.firstChild.data == "firstsecond"
797 , "testNormalize -- result")
798 doc.unlink()
799
800 doc = parseString("<doc/>")
801 root = doc.documentElement
802 root.appendChild(doc.createTextNode(""))
803 doc.normalize()
804 confirm(len(root.childNodes) == 0
805 and root.childNodes.length == 0,
806 "testNormalize -- single empty node removed")
807 doc.unlink()
808
809def testSiblings():
810 doc = parseString("<doc><?pi?>text?<elm/></doc>")
811 root = doc.documentElement
812 (pi, text, elm) = root.childNodes
813
814 confirm(pi.nextSibling is text and
815 pi.previousSibling is None and
816 text.nextSibling is elm and
817 text.previousSibling is pi and
818 elm.nextSibling is None and
819 elm.previousSibling is text, "testSiblings")
820
821 doc.unlink()
822
823def testParents():
824 doc = parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
825 root = doc.documentElement
826 elm1 = root.childNodes[0]
827 (elm2a, elm2b) = elm1.childNodes
828 elm3 = elm2b.childNodes[0]
829
830 confirm(root.parentNode is doc and
831 elm1.parentNode is root and
832 elm2a.parentNode is elm1 and
833 elm2b.parentNode is elm1 and
834 elm3.parentNode is elm2b, "testParents")
835
836 doc.unlink()
837
838def testNodeListItem():
839 doc = parseString("<doc><e/><e/></doc>")
840 children = doc.childNodes
841 docelem = children[0]
842 confirm(children[0] is children.item(0)
843 and children.item(1) is None
844 and docelem.childNodes.item(0) is docelem.childNodes[0]
845 and docelem.childNodes.item(1) is docelem.childNodes[1]
846 and docelem.childNodes.item(0).childNodes.item(0) is None,
847 "test NodeList.item()")
848 doc.unlink()
849
850def testSAX2DOM():
851 from xml.dom import pulldom
852
853 sax2dom = pulldom.SAX2DOM()
854 sax2dom.startDocument()
855 sax2dom.startElement("doc", {})
856 sax2dom.characters("text")
857 sax2dom.startElement("subelm", {})
858 sax2dom.characters("text")
859 sax2dom.endElement("subelm")
860 sax2dom.characters("text")
861 sax2dom.endElement("doc")
862 sax2dom.endDocument()
863
864 doc = sax2dom.document
865 root = doc.documentElement
866 (text1, elm1, text2) = root.childNodes
867 text3 = elm1.childNodes[0]
868
869 confirm(text1.previousSibling is None and
870 text1.nextSibling is elm1 and
871 elm1.previousSibling is text1 and
872 elm1.nextSibling is text2 and
873 text2.previousSibling is elm1 and
874 text2.nextSibling is None and
875 text3.previousSibling is None and
876 text3.nextSibling is None, "testSAX2DOM - siblings")
877
878 confirm(root.parentNode is doc and
879 text1.parentNode is root and
880 elm1.parentNode is root and
881 text2.parentNode is root and
882 text3.parentNode is elm1, "testSAX2DOM - parents")
883
884 doc.unlink()
885
886def testEncodings():
887 doc = parseString('<foo>&#x20ac;</foo>')
888 confirm(doc.toxml() == u'<?xml version="1.0" ?><foo>\u20ac</foo>'
889 and doc.toxml('utf-8') == '<?xml version="1.0" encoding="utf-8"?><foo>\xe2\x82\xac</foo>'
890 and doc.toxml('iso-8859-15') == '<?xml version="1.0" encoding="iso-8859-15"?><foo>\xa4</foo>',
891 "testEncodings - encoding EURO SIGN")
892 doc.unlink()
893
894class UserDataHandler:
895 called = 0
896 def handle(self, operation, key, data, src, dst):
897 dst.setUserData(key, data + 1, self)
898 src.setUserData(key, None, None)
899 self.called = 1
900
901def testUserData():
902 dom = Document()
903 n = dom.createElement('e')
904 confirm(n.getUserData("foo") is None)
905 n.setUserData("foo", None, None)
906 confirm(n.getUserData("foo") is None)
907 n.setUserData("foo", 12, 12)
908 n.setUserData("bar", 13, 13)
909 confirm(n.getUserData("foo") == 12)
910 confirm(n.getUserData("bar") == 13)
911 n.setUserData("foo", None, None)
912 confirm(n.getUserData("foo") is None)
913 confirm(n.getUserData("bar") == 13)
914
915 handler = UserDataHandler()
916 n.setUserData("bar", 12, handler)
917 c = n.cloneNode(1)
918 confirm(handler.called
919 and n.getUserData("bar") is None
920 and c.getUserData("bar") == 13)
921 n.unlink()
922 c.unlink()
923 dom.unlink()
924
925def testRenameAttribute():
926 doc = parseString("<doc a='v'/>")
927 elem = doc.documentElement
928 attrmap = elem.attributes
929 attr = elem.attributes['a']
930
931 # Simple renaming
932 attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "b")
933 confirm(attr.name == "b"
934 and attr.nodeName == "b"
935 and attr.localName is None
936 and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
937 and attr.prefix is None
938 and attr.value == "v"
939 and elem.getAttributeNode("a") is None
940 and elem.getAttributeNode("b").isSameNode(attr)
941 and attrmap["b"].isSameNode(attr)
942 and attr.ownerDocument.isSameNode(doc)
943 and attr.ownerElement.isSameNode(elem))
944
945 # Rename to have a namespace, no prefix
946 attr = doc.renameNode(attr, "http://xml.python.org/ns", "c")
947 confirm(attr.name == "c"
948 and attr.nodeName == "c"
949 and attr.localName == "c"
950 and attr.namespaceURI == "http://xml.python.org/ns"
951 and attr.prefix is None
952 and attr.value == "v"
953 and elem.getAttributeNode("a") is None
954 and elem.getAttributeNode("b") is None
955 and elem.getAttributeNode("c").isSameNode(attr)
956 and elem.getAttributeNodeNS(
957 "http://xml.python.org/ns", "c").isSameNode(attr)
958 and attrmap["c"].isSameNode(attr)
959 and attrmap[("http://xml.python.org/ns", "c")].isSameNode(attr))
960
961 # Rename to have a namespace, with prefix
962 attr = doc.renameNode(attr, "http://xml.python.org/ns2", "p:d")
963 confirm(attr.name == "p:d"
964 and attr.nodeName == "p:d"
965 and attr.localName == "d"
966 and attr.namespaceURI == "http://xml.python.org/ns2"
967 and attr.prefix == "p"
968 and attr.value == "v"
969 and elem.getAttributeNode("a") is None
970 and elem.getAttributeNode("b") is None
971 and elem.getAttributeNode("c") is None
972 and elem.getAttributeNodeNS(
973 "http://xml.python.org/ns", "c") is None
974 and elem.getAttributeNode("p:d").isSameNode(attr)
975 and elem.getAttributeNodeNS(
976 "http://xml.python.org/ns2", "d").isSameNode(attr)
977 and attrmap["p:d"].isSameNode(attr)
978 and attrmap[("http://xml.python.org/ns2", "d")].isSameNode(attr))
979
980 # Rename back to a simple non-NS node
981 attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "e")
982 confirm(attr.name == "e"
983 and attr.nodeName == "e"
984 and attr.localName is None
985 and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
986 and attr.prefix is None
987 and attr.value == "v"
988 and elem.getAttributeNode("a") is None
989 and elem.getAttributeNode("b") is None
990 and elem.getAttributeNode("c") is None
991 and elem.getAttributeNode("p:d") is None
992 and elem.getAttributeNodeNS(
993 "http://xml.python.org/ns", "c") is None
994 and elem.getAttributeNode("e").isSameNode(attr)
995 and attrmap["e"].isSameNode(attr))
996
997 try:
998 doc.renameNode(attr, "http://xml.python.org/ns", "xmlns")
999 except xml.dom.NamespaceErr:
1000 pass
1001 else:
1002 print "expected NamespaceErr"
1003
1004 checkRenameNodeSharedConstraints(doc, attr)
1005 doc.unlink()
1006
1007def testRenameElement():
1008 doc = parseString("<doc/>")
1009 elem = doc.documentElement
1010
1011 # Simple renaming
1012 elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "a")
1013 confirm(elem.tagName == "a"
1014 and elem.nodeName == "a"
1015 and elem.localName is None
1016 and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
1017 and elem.prefix is None
1018 and elem.ownerDocument.isSameNode(doc))
1019
1020 # Rename to have a namespace, no prefix
1021 elem = doc.renameNode(elem, "http://xml.python.org/ns", "b")
1022 confirm(elem.tagName == "b"
1023 and elem.nodeName == "b"
1024 and elem.localName == "b"
1025 and elem.namespaceURI == "http://xml.python.org/ns"
1026 and elem.prefix is None
1027 and elem.ownerDocument.isSameNode(doc))
1028
1029 # Rename to have a namespace, with prefix
1030 elem = doc.renameNode(elem, "http://xml.python.org/ns2", "p:c")
1031 confirm(elem.tagName == "p:c"
1032 and elem.nodeName == "p:c"
1033 and elem.localName == "c"
1034 and elem.namespaceURI == "http://xml.python.org/ns2"
1035 and elem.prefix == "p"
1036 and elem.ownerDocument.isSameNode(doc))
1037
1038 # Rename back to a simple non-NS node
1039 elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "d")
1040 confirm(elem.tagName == "d"
1041 and elem.nodeName == "d"
1042 and elem.localName is None
1043 and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
1044 and elem.prefix is None
1045 and elem.ownerDocument.isSameNode(doc))
1046
1047 checkRenameNodeSharedConstraints(doc, elem)
1048 doc.unlink()
1049
1050def checkRenameNodeSharedConstraints(doc, node):
1051 # Make sure illegal NS usage is detected:
1052 try:
1053 doc.renameNode(node, "http://xml.python.org/ns", "xmlns:foo")
1054 except xml.dom.NamespaceErr:
1055 pass
1056 else:
1057 print "expected NamespaceErr"
1058
1059 doc2 = parseString("<doc/>")
1060 try:
1061 doc2.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo")
1062 except xml.dom.WrongDocumentErr:
1063 pass
1064 else:
1065 print "expected WrongDocumentErr"
1066
1067def testRenameOther():
1068 # We have to create a comment node explicitly since not all DOM
1069 # builders used with minidom add comments to the DOM.
1070 doc = xml.dom.minidom.getDOMImplementation().createDocument(
1071 xml.dom.EMPTY_NAMESPACE, "e", None)
1072 node = doc.createComment("comment")
1073 try:
1074 doc.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo")
1075 except xml.dom.NotSupportedErr:
1076 pass
1077 else:
1078 print "expected NotSupportedErr when renaming comment node"
1079 doc.unlink()
1080
1081def checkWholeText(node, s):
1082 t = node.wholeText
1083 confirm(t == s, "looking for %s, found %s" % (repr(s), repr(t)))
1084
1085def testWholeText():
1086 doc = parseString("<doc>a</doc>")
1087 elem = doc.documentElement
1088 text = elem.childNodes[0]
1089 assert text.nodeType == Node.TEXT_NODE
1090
1091 checkWholeText(text, "a")
1092 elem.appendChild(doc.createTextNode("b"))
1093 checkWholeText(text, "ab")
1094 elem.insertBefore(doc.createCDATASection("c"), text)
1095 checkWholeText(text, "cab")
1096
1097 # make sure we don't cross other nodes
1098 splitter = doc.createComment("comment")
1099 elem.appendChild(splitter)
1100 text2 = doc.createTextNode("d")
1101 elem.appendChild(text2)
1102 checkWholeText(text, "cab")
1103 checkWholeText(text2, "d")
1104
1105 x = doc.createElement("x")
1106 elem.replaceChild(x, splitter)
1107 splitter = x
1108 checkWholeText(text, "cab")
1109 checkWholeText(text2, "d")
1110
1111 x = doc.createProcessingInstruction("y", "z")
1112 elem.replaceChild(x, splitter)
1113 splitter = x
1114 checkWholeText(text, "cab")
1115 checkWholeText(text2, "d")
1116
1117 elem.removeChild(splitter)
1118 checkWholeText(text, "cabd")
1119 checkWholeText(text2, "cabd")
1120
1121def testReplaceWholeText():
1122 def setup():
1123 doc = parseString("<doc>a<e/>d</doc>")
1124 elem = doc.documentElement
1125 text1 = elem.firstChild
1126 text2 = elem.lastChild
1127 splitter = text1.nextSibling
1128 elem.insertBefore(doc.createTextNode("b"), splitter)
1129 elem.insertBefore(doc.createCDATASection("c"), text1)
1130 return doc, elem, text1, splitter, text2
1131
1132 doc, elem, text1, splitter, text2 = setup()
1133 text = text1.replaceWholeText("new content")
1134 checkWholeText(text, "new content")
1135 checkWholeText(text2, "d")
1136 confirm(len(elem.childNodes) == 3)
1137
1138 doc, elem, text1, splitter, text2 = setup()
1139 text = text2.replaceWholeText("new content")
1140 checkWholeText(text, "new content")
1141 checkWholeText(text1, "cab")
1142 confirm(len(elem.childNodes) == 5)
1143
1144 doc, elem, text1, splitter, text2 = setup()
1145 text = text1.replaceWholeText("")
1146 checkWholeText(text2, "d")
1147 confirm(text is None
1148 and len(elem.childNodes) == 2)
1149
1150def testSchemaType():
1151 doc = parseString(
1152 "<!DOCTYPE doc [\n"
1153 " <!ENTITY e1 SYSTEM 'http://xml.python.org/e1'>\n"
1154 " <!ENTITY e2 SYSTEM 'http://xml.python.org/e2'>\n"
1155 " <!ATTLIST doc id ID #IMPLIED \n"
1156 " ref IDREF #IMPLIED \n"
1157 " refs IDREFS #IMPLIED \n"
1158 " enum (a|b) #IMPLIED \n"
1159 " ent ENTITY #IMPLIED \n"
1160 " ents ENTITIES #IMPLIED \n"
1161 " nm NMTOKEN #IMPLIED \n"
1162 " nms NMTOKENS #IMPLIED \n"
1163 " text CDATA #IMPLIED \n"
1164 " >\n"
1165 "]><doc id='name' notid='name' text='splat!' enum='b'"
1166 " ref='name' refs='name name' ent='e1' ents='e1 e2'"
1167 " nm='123' nms='123 abc' />")
1168 elem = doc.documentElement
1169 # We don't want to rely on any specific loader at this point, so
1170 # just make sure we can get to all the names, and that the
1171 # DTD-based namespace is right. The names can vary by loader
1172 # since each supports a different level of DTD information.
1173 t = elem.schemaType
1174 confirm(t.name is None
1175 and t.namespace == xml.dom.EMPTY_NAMESPACE)
1176 names = "id notid text enum ref refs ent ents nm nms".split()
1177 for name in names:
1178 a = elem.getAttributeNode(name)
1179 t = a.schemaType
1180 confirm(hasattr(t, "name")
1181 and t.namespace == xml.dom.EMPTY_NAMESPACE)
1182
1183def testSetIdAttribute():
1184 doc = parseString("<doc a1='v' a2='w'/>")
1185 e = doc.documentElement
1186 a1 = e.getAttributeNode("a1")
1187 a2 = e.getAttributeNode("a2")
1188 confirm(doc.getElementById("v") is None
1189 and not a1.isId
1190 and not a2.isId)
1191 e.setIdAttribute("a1")
1192 confirm(e.isSameNode(doc.getElementById("v"))
1193 and a1.isId
1194 and not a2.isId)
1195 e.setIdAttribute("a2")
1196 confirm(e.isSameNode(doc.getElementById("v"))
1197 and e.isSameNode(doc.getElementById("w"))
1198 and a1.isId
1199 and a2.isId)
1200 # replace the a1 node; the new node should *not* be an ID
1201 a3 = doc.createAttribute("a1")
1202 a3.value = "v"
1203 e.setAttributeNode(a3)
1204 confirm(doc.getElementById("v") is None
1205 and e.isSameNode(doc.getElementById("w"))
1206 and not a1.isId
1207 and a2.isId
1208 and not a3.isId)
1209 # renaming an attribute should not affect its ID-ness:
1210 doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
1211 confirm(e.isSameNode(doc.getElementById("w"))
1212 and a2.isId)
1213
1214def testSetIdAttributeNS():
1215 NS1 = "http://xml.python.org/ns1"
1216 NS2 = "http://xml.python.org/ns2"
1217 doc = parseString("<doc"
1218 " xmlns:ns1='" + NS1 + "'"
1219 " xmlns:ns2='" + NS2 + "'"
1220 " ns1:a1='v' ns2:a2='w'/>")
1221 e = doc.documentElement
1222 a1 = e.getAttributeNodeNS(NS1, "a1")
1223 a2 = e.getAttributeNodeNS(NS2, "a2")
1224 confirm(doc.getElementById("v") is None
1225 and not a1.isId
1226 and not a2.isId)
1227 e.setIdAttributeNS(NS1, "a1")
1228 confirm(e.isSameNode(doc.getElementById("v"))
1229 and a1.isId
1230 and not a2.isId)
1231 e.setIdAttributeNS(NS2, "a2")
1232 confirm(e.isSameNode(doc.getElementById("v"))
1233 and e.isSameNode(doc.getElementById("w"))
1234 and a1.isId
1235 and a2.isId)
1236 # replace the a1 node; the new node should *not* be an ID
1237 a3 = doc.createAttributeNS(NS1, "a1")
1238 a3.value = "v"
1239 e.setAttributeNode(a3)
1240 confirm(e.isSameNode(doc.getElementById("w")))
1241 confirm(not a1.isId)
1242 confirm(a2.isId)
1243 confirm(not a3.isId)
1244 confirm(doc.getElementById("v") is None)
1245 # renaming an attribute should not affect its ID-ness:
1246 doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
1247 confirm(e.isSameNode(doc.getElementById("w"))
1248 and a2.isId)
1249
1250def testSetIdAttributeNode():
1251 NS1 = "http://xml.python.org/ns1"
1252 NS2 = "http://xml.python.org/ns2"
1253 doc = parseString("<doc"
1254 " xmlns:ns1='" + NS1 + "'"
1255 " xmlns:ns2='" + NS2 + "'"
1256 " ns1:a1='v' ns2:a2='w'/>")
1257 e = doc.documentElement
1258 a1 = e.getAttributeNodeNS(NS1, "a1")
1259 a2 = e.getAttributeNodeNS(NS2, "a2")
1260 confirm(doc.getElementById("v") is None
1261 and not a1.isId
1262 and not a2.isId)
1263 e.setIdAttributeNode(a1)
1264 confirm(e.isSameNode(doc.getElementById("v"))
1265 and a1.isId
1266 and not a2.isId)
1267 e.setIdAttributeNode(a2)
1268 confirm(e.isSameNode(doc.getElementById("v"))
1269 and e.isSameNode(doc.getElementById("w"))
1270 and a1.isId
1271 and a2.isId)
1272 # replace the a1 node; the new node should *not* be an ID
1273 a3 = doc.createAttributeNS(NS1, "a1")
1274 a3.value = "v"
1275 e.setAttributeNode(a3)
1276 confirm(e.isSameNode(doc.getElementById("w")))
1277 confirm(not a1.isId)
1278 confirm(a2.isId)
1279 confirm(not a3.isId)
1280 confirm(doc.getElementById("v") is None)
1281 # renaming an attribute should not affect its ID-ness:
1282 doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
1283 confirm(e.isSameNode(doc.getElementById("w"))
1284 and a2.isId)
1285
1286def testPickledDocument():
1287 doc = parseString("<?xml version='1.0' encoding='us-ascii'?>\n"
1288 "<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'"
1289 " 'http://xml.python.org/system' [\n"
1290 " <!ELEMENT e EMPTY>\n"
1291 " <!ENTITY ent SYSTEM 'http://xml.python.org/entity'>\n"
1292 "]><doc attr='value'> text\n"
1293 "<?pi sample?> <!-- comment --> <e/> </doc>")
1294 s = pickle.dumps(doc)
1295 doc2 = pickle.loads(s)
1296 stack = [(doc, doc2)]
1297 while stack:
1298 n1, n2 = stack.pop()
1299 confirm(n1.nodeType == n2.nodeType
1300 and len(n1.childNodes) == len(n2.childNodes)
1301 and n1.nodeName == n2.nodeName
1302 and not n1.isSameNode(n2)
1303 and not n2.isSameNode(n1))
1304 if n1.nodeType == Node.DOCUMENT_TYPE_NODE:
1305 len(n1.entities)
1306 len(n2.entities)
1307 len(n1.notations)
1308 len(n2.notations)
1309 confirm(len(n1.entities) == len(n2.entities)
1310 and len(n1.notations) == len(n2.notations))
1311 for i in range(len(n1.notations)):
1312 no1 = n1.notations.item(i)
1313 no2 = n1.notations.item(i)
1314 confirm(no1.name == no2.name
1315 and no1.publicId == no2.publicId
1316 and no1.systemId == no2.systemId)
1317 statck.append((no1, no2))
1318 for i in range(len(n1.entities)):
1319 e1 = n1.entities.item(i)
1320 e2 = n2.entities.item(i)
1321 confirm(e1.notationName == e2.notationName
1322 and e1.publicId == e2.publicId
1323 and e1.systemId == e2.systemId)
1324 stack.append((e1, e2))
1325 if n1.nodeType != Node.DOCUMENT_NODE:
1326 confirm(n1.ownerDocument.isSameNode(doc)
1327 and n2.ownerDocument.isSameNode(doc2))
1328 for i in range(len(n1.childNodes)):
1329 stack.append((n1.childNodes[i], n2.childNodes[i]))
1330
1331
1332# --- MAIN PROGRAM
1333
1334names = globals().keys()
1335names.sort()
1336
1337failed = []
1338
1339try:
1340 Node.allnodes
1341except AttributeError:
1342 # We don't actually have the minidom from the standard library,
1343 # but are picking up the PyXML version from site-packages.
1344 def check_allnodes():
1345 pass
1346else:
1347 def check_allnodes():
1348 confirm(len(Node.allnodes) == 0,
1349 "assertion: len(Node.allnodes) == 0")
1350 if len(Node.allnodes):
1351 print "Garbage left over:"
1352 if verbose:
1353 print Node.allnodes.items()[0:10]
1354 else:
1355 # Don't print specific nodes if repeatable results
1356 # are needed
1357 print len(Node.allnodes)
1358 Node.allnodes = {}
1359
1360for name in names:
1361 if name.startswith("test"):
1362 func = globals()[name]
1363 try:
1364 func()
1365 check_allnodes()
1366 except:
1367 failed.append(name)
1368 print "Test Failed: ", name
1369 sys.stdout.flush()
1370 traceback.print_exception(*sys.exc_info())
1371 print repr(sys.exc_info()[1])
1372 Node.allnodes = {}
1373
1374if failed:
1375 print "\n\n\n**** Check for failures in these tests:"
1376 for name in failed:
1377 print " " + name