PyXR

c:\python24\lib \ test \ test_minidom.py



0001 # test for xml.dom.minidom
0002 
0003 import os
0004 import sys
0005 import pickle
0006 import traceback
0007 from StringIO import StringIO
0008 from test.test_support import verbose
0009 
0010 import xml.dom
0011 import xml.dom.minidom
0012 import xml.parsers.expat
0013 
0014 from xml.dom.minidom import parse, Node, Document, parseString
0015 from xml.dom.minidom import getDOMImplementation
0016 
0017 
0018 if __name__ == "__main__":
0019     base = sys.argv[0]
0020 else:
0021     base = __file__
0022 tstfile = os.path.join(os.path.dirname(base), "test"+os.extsep+"xml")
0023 del base
0024 
0025 def confirm(test, testname = "Test"):
0026     if not test:
0027         print "Failed " + testname
0028         raise Exception
0029 
0030 def testParseFromFile():
0031     dom = parse(StringIO(open(tstfile).read()))
0032     dom.unlink()
0033     confirm(isinstance(dom,Document))
0034 
0035 def testGetElementsByTagName():
0036     dom = parse(tstfile)
0037     confirm(dom.getElementsByTagName("LI") == \
0038             dom.documentElement.getElementsByTagName("LI"))
0039     dom.unlink()
0040 
0041 def testInsertBefore():
0042     dom = parseString("<doc><foo/></doc>")
0043     root = dom.documentElement
0044     elem = root.childNodes[0]
0045     nelem = dom.createElement("element")
0046     root.insertBefore(nelem, elem)
0047     confirm(len(root.childNodes) == 2
0048             and root.childNodes.length == 2
0049             and root.childNodes[0] is nelem
0050             and root.childNodes.item(0) is nelem
0051             and root.childNodes[1] is elem
0052             and root.childNodes.item(1) is elem
0053             and root.firstChild is nelem
0054             and root.lastChild is elem
0055             and root.toxml() == "<doc><element/><foo/></doc>"
0056             , "testInsertBefore -- node properly placed in tree")
0057     nelem = dom.createElement("element")
0058     root.insertBefore(nelem, None)
0059     confirm(len(root.childNodes) == 3
0060             and root.childNodes.length == 3
0061             and root.childNodes[1] is elem
0062             and root.childNodes.item(1) is elem
0063             and root.childNodes[2] is nelem
0064             and root.childNodes.item(2) is nelem
0065             and root.lastChild is nelem
0066             and nelem.previousSibling is elem
0067             and root.toxml() == "<doc><element/><foo/><element/></doc>"
0068             , "testInsertBefore -- node properly placed in tree")
0069     nelem2 = dom.createElement("bar")
0070     root.insertBefore(nelem2, nelem)
0071     confirm(len(root.childNodes) == 4
0072             and root.childNodes.length == 4
0073             and root.childNodes[2] is nelem2
0074             and root.childNodes.item(2) is nelem2
0075             and root.childNodes[3] is nelem
0076             and root.childNodes.item(3) is nelem
0077             and nelem2.nextSibling is nelem
0078             and nelem.previousSibling is nelem2
0079             and root.toxml() == "<doc><element/><foo/><bar/><element/></doc>"
0080             , "testInsertBefore -- node properly placed in tree")
0081     dom.unlink()
0082 
0083 def _create_fragment_test_nodes():
0084     dom = parseString("<doc/>")
0085     orig = dom.createTextNode("original")
0086     c1 = dom.createTextNode("foo")
0087     c2 = dom.createTextNode("bar")
0088     c3 = dom.createTextNode("bat")
0089     dom.documentElement.appendChild(orig)
0090     frag = dom.createDocumentFragment()
0091     frag.appendChild(c1)
0092     frag.appendChild(c2)
0093     frag.appendChild(c3)
0094     return dom, orig, c1, c2, c3, frag
0095 
0096 def testInsertBeforeFragment():
0097     dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
0098     dom.documentElement.insertBefore(frag, None)
0099     confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
0100             "insertBefore(<fragment>, None)")
0101     frag.unlink()
0102     dom.unlink()
0103     #
0104     dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
0105     dom.documentElement.insertBefore(frag, orig)
0106     confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3, orig),
0107             "insertBefore(<fragment>, orig)")
0108     frag.unlink()
0109     dom.unlink()
0110 
0111 def testAppendChild():
0112     dom = parse(tstfile)
0113     dom.documentElement.appendChild(dom.createComment(u"Hello"))
0114     confirm(dom.documentElement.childNodes[-1].nodeName == "#comment")
0115     confirm(dom.documentElement.childNodes[-1].data == "Hello")
0116     dom.unlink()
0117 
0118 def testAppendChildFragment():
0119     dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
0120     dom.documentElement.appendChild(frag)
0121     confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
0122             "appendChild(<fragment>)")
0123     frag.unlink()
0124     dom.unlink()
0125 
0126 def testReplaceChildFragment():
0127     dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
0128     dom.documentElement.replaceChild(frag, orig)
0129     orig.unlink()
0130     confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3),
0131             "replaceChild(<fragment>)")
0132     frag.unlink()
0133     dom.unlink()
0134 
0135 def testLegalChildren():
0136     dom = Document()
0137     elem = dom.createElement('element')
0138     text = dom.createTextNode('text')
0139 
0140     try: dom.appendChild(text)
0141     except xml.dom.HierarchyRequestErr: pass
0142     else:
0143         print "dom.appendChild didn't raise HierarchyRequestErr"
0144 
0145     dom.appendChild(elem)
0146     try: dom.insertBefore(text, elem)
0147     except xml.dom.HierarchyRequestErr: pass
0148     else:
0149         print "dom.appendChild didn't raise HierarchyRequestErr"
0150 
0151     try: dom.replaceChild(text, elem)
0152     except xml.dom.HierarchyRequestErr: pass
0153     else:
0154         print "dom.appendChild didn't raise HierarchyRequestErr"
0155 
0156     nodemap = elem.attributes
0157     try: nodemap.setNamedItem(text)
0158     except xml.dom.HierarchyRequestErr: pass
0159     else:
0160         print "NamedNodeMap.setNamedItem didn't raise HierarchyRequestErr"
0161 
0162     try: nodemap.setNamedItemNS(text)
0163     except xml.dom.HierarchyRequestErr: pass
0164     else:
0165         print "NamedNodeMap.setNamedItemNS didn't raise HierarchyRequestErr"
0166 
0167     elem.appendChild(text)
0168     dom.unlink()
0169 
0170 def testNamedNodeMapSetItem():
0171     dom = Document()
0172     elem = dom.createElement('element')
0173     attrs = elem.attributes
0174     attrs["foo"] = "bar"
0175     a = attrs.item(0)
0176     confirm(a.ownerDocument is dom,
0177             "NamedNodeMap.__setitem__() sets ownerDocument")
0178     confirm(a.ownerElement is elem,
0179             "NamedNodeMap.__setitem__() sets ownerElement")
0180     confirm(a.value == "bar",
0181             "NamedNodeMap.__setitem__() sets value")
0182     confirm(a.nodeValue == "bar",
0183             "NamedNodeMap.__setitem__() sets nodeValue")
0184     elem.unlink()
0185     dom.unlink()
0186 
0187 def testNonZero():
0188     dom = parse(tstfile)
0189     confirm(dom)# should not be zero
0190     dom.appendChild(dom.createComment("foo"))
0191     confirm(not dom.childNodes[-1].childNodes)
0192     dom.unlink()
0193 
0194 def testUnlink():
0195     dom = parse(tstfile)
0196     dom.unlink()
0197 
0198 def testElement():
0199     dom = Document()
0200     dom.appendChild(dom.createElement("abc"))
0201     confirm(dom.documentElement)
0202     dom.unlink()
0203 
0204 def testAAA():
0205     dom = parseString("<abc/>")
0206     el = dom.documentElement
0207     el.setAttribute("spam", "jam2")
0208     confirm(el.toxml() == '<abc spam="jam2"/>', "testAAA")
0209     a = el.getAttributeNode("spam")
0210     confirm(a.ownerDocument is dom,
0211             "setAttribute() sets ownerDocument")
0212     confirm(a.ownerElement is dom.documentElement,
0213             "setAttribute() sets ownerElement")
0214     dom.unlink()
0215 
0216 def testAAB():
0217     dom = parseString("<abc/>")
0218     el = dom.documentElement
0219     el.setAttribute("spam", "jam")
0220     el.setAttribute("spam", "jam2")
0221     confirm(el.toxml() == '<abc spam="jam2"/>', "testAAB")
0222     dom.unlink()
0223 
0224 def testAddAttr():
0225     dom = Document()
0226     child = dom.appendChild(dom.createElement("abc"))
0227 
0228     child.setAttribute("def", "ghi")
0229     confirm(child.getAttribute("def") == "ghi")
0230     confirm(child.attributes["def"].value == "ghi")
0231 
0232     child.setAttribute("jkl", "mno")
0233     confirm(child.getAttribute("jkl") == "mno")
0234     confirm(child.attributes["jkl"].value == "mno")
0235 
0236     confirm(len(child.attributes) == 2)
0237 
0238     child.setAttribute("def", "newval")
0239     confirm(child.getAttribute("def") == "newval")
0240     confirm(child.attributes["def"].value == "newval")
0241 
0242     confirm(len(child.attributes) == 2)
0243     dom.unlink()
0244 
0245 def testDeleteAttr():
0246     dom = Document()
0247     child = dom.appendChild(dom.createElement("abc"))
0248 
0249     confirm(len(child.attributes) == 0)
0250     child.setAttribute("def", "ghi")
0251     confirm(len(child.attributes) == 1)
0252     del child.attributes["def"]
0253     confirm(len(child.attributes) == 0)
0254     dom.unlink()
0255 
0256 def testRemoveAttr():
0257     dom = Document()
0258     child = dom.appendChild(dom.createElement("abc"))
0259 
0260     child.setAttribute("def", "ghi")
0261     confirm(len(child.attributes) == 1)
0262     child.removeAttribute("def")
0263     confirm(len(child.attributes) == 0)
0264 
0265     dom.unlink()
0266 
0267 def testRemoveAttrNS():
0268     dom = Document()
0269     child = dom.appendChild(
0270             dom.createElementNS("http://www.python.org", "python:abc"))
0271     child.setAttributeNS("http://www.w3.org", "xmlns:python",
0272                                             "http://www.python.org")
0273     child.setAttributeNS("http://www.python.org", "python:abcattr", "foo")
0274     confirm(len(child.attributes) == 2)
0275     child.removeAttributeNS("http://www.python.org", "abcattr")
0276     confirm(len(child.attributes) == 1)
0277 
0278     dom.unlink()
0279 
0280 def testRemoveAttributeNode():
0281     dom = Document()
0282     child = dom.appendChild(dom.createElement("foo"))
0283     child.setAttribute("spam", "jam")
0284     confirm(len(child.attributes) == 1)
0285     node = child.getAttributeNode("spam")
0286     child.removeAttributeNode(node)
0287     confirm(len(child.attributes) == 0
0288             and child.getAttributeNode("spam") is None)
0289 
0290     dom.unlink()
0291 
0292 def testChangeAttr():
0293     dom = parseString("<abc/>")
0294     el = dom.documentElement
0295     el.setAttribute("spam", "jam")
0296     confirm(len(el.attributes) == 1)
0297     el.setAttribute("spam", "bam")
0298     # Set this attribute to be an ID and make sure that doesn't change
0299     # when changing the value:
0300     el.setIdAttribute("spam")
0301     confirm(len(el.attributes) == 1
0302             and el.attributes["spam"].value == "bam"
0303             and el.attributes["spam"].nodeValue == "bam"
0304             and el.getAttribute("spam") == "bam"
0305             and el.getAttributeNode("spam").isId)
0306     el.attributes["spam"] = "ham"
0307     confirm(len(el.attributes) == 1
0308             and el.attributes["spam"].value == "ham"
0309             and el.attributes["spam"].nodeValue == "ham"
0310             and el.getAttribute("spam") == "ham"
0311             and el.attributes["spam"].isId)
0312     el.setAttribute("spam2", "bam")
0313     confirm(len(el.attributes) == 2
0314             and el.attributes["spam"].value == "ham"
0315             and el.attributes["spam"].nodeValue == "ham"
0316             and el.getAttribute("spam") == "ham"
0317             and el.attributes["spam2"].value == "bam"
0318             and el.attributes["spam2"].nodeValue == "bam"
0319             and el.getAttribute("spam2") == "bam")
0320     el.attributes["spam2"] = "bam2"
0321     confirm(len(el.attributes) == 2
0322             and el.attributes["spam"].value == "ham"
0323             and el.attributes["spam"].nodeValue == "ham"
0324             and el.getAttribute("spam") == "ham"
0325             and el.attributes["spam2"].value == "bam2"
0326             and el.attributes["spam2"].nodeValue == "bam2"
0327             and el.getAttribute("spam2") == "bam2")
0328     dom.unlink()
0329 
0330 def testGetAttrList():
0331     pass
0332 
0333 def testGetAttrValues(): pass
0334 
0335 def testGetAttrLength(): pass
0336 
0337 def testGetAttribute(): pass
0338 
0339 def testGetAttributeNS(): pass
0340 
0341 def testGetAttributeNode(): pass
0342 
0343 def testGetElementsByTagNameNS():
0344     d="""<foo xmlns:minidom='http://pyxml.sf.net/minidom'>
0345     <minidom:myelem/>
0346     </foo>"""
0347     dom = parseString(d)
0348     elems = dom.getElementsByTagNameNS("http://pyxml.sf.net/minidom", "myelem")
0349     confirm(len(elems) == 1
0350             and elems[0].namespaceURI == "http://pyxml.sf.net/minidom"
0351             and elems[0].localName == "myelem"
0352             and elems[0].prefix == "minidom"
0353             and elems[0].tagName == "minidom:myelem"
0354             and elems[0].nodeName == "minidom:myelem")
0355     dom.unlink()
0356 
0357 def get_empty_nodelist_from_elements_by_tagName_ns_helper(doc, nsuri, lname):
0358     nodelist = doc.getElementsByTagNameNS(nsuri, lname)
0359     confirm(len(nodelist) == 0)
0360 
0361 def testGetEmptyNodeListFromElementsByTagNameNS():
0362     doc = parseString('<doc/>')
0363     get_empty_nodelist_from_elements_by_tagName_ns_helper(
0364         doc, 'http://xml.python.org/namespaces/a', 'localname')
0365     get_empty_nodelist_from_elements_by_tagName_ns_helper(
0366         doc, '*', 'splat')
0367     get_empty_nodelist_from_elements_by_tagName_ns_helper(
0368         doc, 'http://xml.python.org/namespaces/a', '*')
0369 
0370     doc = parseString('<doc xmlns="http://xml.python.org/splat"><e/></doc>')
0371     get_empty_nodelist_from_elements_by_tagName_ns_helper(
0372         doc, "http://xml.python.org/splat", "not-there")
0373     get_empty_nodelist_from_elements_by_tagName_ns_helper(
0374         doc, "*", "not-there")
0375     get_empty_nodelist_from_elements_by_tagName_ns_helper(
0376         doc, "http://somewhere.else.net/not-there", "e")
0377 
0378 def testElementReprAndStr():
0379     dom = Document()
0380     el = dom.appendChild(dom.createElement("abc"))
0381     string1 = repr(el)
0382     string2 = str(el)
0383     confirm(string1 == string2)
0384     dom.unlink()
0385 
0386 # commented out until Fredrick's fix is checked in
0387 def _testElementReprAndStrUnicode():
0388     dom = Document()
0389     el = dom.appendChild(dom.createElement(u"abc"))
0390     string1 = repr(el)
0391     string2 = str(el)
0392     confirm(string1 == string2)
0393     dom.unlink()
0394 
0395 # commented out until Fredrick's fix is checked in
0396 def _testElementReprAndStrUnicodeNS():
0397     dom = Document()
0398     el = dom.appendChild(
0399         dom.createElementNS(u"http://www.slashdot.org", u"slash:abc"))
0400     string1 = repr(el)
0401     string2 = str(el)
0402     confirm(string1 == string2)
0403     confirm(string1.find("slash:abc") != -1)
0404     dom.unlink()
0405 
0406 def testAttributeRepr():
0407     dom = Document()
0408     el = dom.appendChild(dom.createElement(u"abc"))
0409     node = el.setAttribute("abc", "def")
0410     confirm(str(node) == repr(node))
0411     dom.unlink()
0412 
0413 def testTextNodeRepr(): pass
0414 
0415 def testWriteXML():
0416     str = '<?xml version="1.0" ?>\n<a b="c"/>'
0417     dom = parseString(str)
0418     domstr = dom.toxml()
0419     dom.unlink()
0420     confirm(str == domstr)
0421 
0422 def testProcessingInstruction():
0423     dom = parseString('<e><?mypi \t\n data \t\n ?></e>')
0424     pi = dom.documentElement.firstChild
0425     confirm(pi.target == "mypi"
0426             and pi.data == "data \t\n "
0427             and pi.nodeName == "mypi"
0428             and pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE
0429             and pi.attributes is None
0430             and not pi.hasChildNodes()
0431             and len(pi.childNodes) == 0
0432             and pi.firstChild is None
0433             and pi.lastChild is None
0434             and pi.localName is None
0435             and pi.namespaceURI == xml.dom.EMPTY_NAMESPACE)
0436 
0437 def testProcessingInstructionRepr(): pass
0438 
0439 def testTextRepr(): pass
0440 
0441 def testWriteText(): pass
0442 
0443 def testDocumentElement(): pass
0444 
0445 def testTooManyDocumentElements():
0446     doc = parseString("<doc/>")
0447     elem = doc.createElement("extra")
0448     try:
0449         doc.appendChild(elem)
0450     except xml.dom.HierarchyRequestErr:
0451         pass
0452     else:
0453         print "Failed to catch expected exception when" \
0454               " adding extra document element."
0455     elem.unlink()
0456     doc.unlink()
0457 
0458 def testCreateElementNS(): pass
0459 
0460 def testCreateAttributeNS(): pass
0461 
0462 def testParse(): pass
0463 
0464 def testParseString(): pass
0465 
0466 def testComment(): pass
0467 
0468 def testAttrListItem(): pass
0469 
0470 def testAttrListItems(): pass
0471 
0472 def testAttrListItemNS(): pass
0473 
0474 def testAttrListKeys(): pass
0475 
0476 def testAttrListKeysNS(): pass
0477 
0478 def testRemoveNamedItem():
0479     doc = parseString("<doc a=''/>")
0480     e = doc.documentElement
0481     attrs = e.attributes
0482     a1 = e.getAttributeNode("a")
0483     a2 = attrs.removeNamedItem("a")
0484     confirm(a1.isSameNode(a2))
0485     try:
0486         attrs.removeNamedItem("a")
0487     except xml.dom.NotFoundErr:
0488         pass
0489 
0490 def testRemoveNamedItemNS():
0491     doc = parseString("<doc xmlns:a='http://xml.python.org/' a:b=''/>")
0492     e = doc.documentElement
0493     attrs = e.attributes
0494     a1 = e.getAttributeNodeNS("http://xml.python.org/", "b")
0495     a2 = attrs.removeNamedItemNS("http://xml.python.org/", "b")
0496     confirm(a1.isSameNode(a2))
0497     try:
0498         attrs.removeNamedItemNS("http://xml.python.org/", "b")
0499     except xml.dom.NotFoundErr:
0500         pass
0501 
0502 def testAttrListValues(): pass
0503 
0504 def testAttrListLength(): pass
0505 
0506 def testAttrList__getitem__(): pass
0507 
0508 def testAttrList__setitem__(): pass
0509 
0510 def testSetAttrValueandNodeValue(): pass
0511 
0512 def testParseElement(): pass
0513 
0514 def testParseAttributes(): pass
0515 
0516 def testParseElementNamespaces(): pass
0517 
0518 def testParseAttributeNamespaces(): pass
0519 
0520 def testParseProcessingInstructions(): pass
0521 
0522 def testChildNodes(): pass
0523 
0524 def testFirstChild(): pass
0525 
0526 def testHasChildNodes(): pass
0527 
0528 def testCloneElementShallow():
0529     dom, clone = _setupCloneElement(0)
0530     confirm(len(clone.childNodes) == 0
0531             and clone.childNodes.length == 0
0532             and clone.parentNode is None
0533             and clone.toxml() == '<doc attr="value"/>'
0534             , "testCloneElementShallow")
0535     dom.unlink()
0536 
0537 def testCloneElementDeep():
0538     dom, clone = _setupCloneElement(1)
0539     confirm(len(clone.childNodes) == 1
0540             and clone.childNodes.length == 1
0541             and clone.parentNode is None
0542             and clone.toxml() == '<doc attr="value"><foo/></doc>'
0543             , "testCloneElementDeep")
0544     dom.unlink()
0545 
0546 def _setupCloneElement(deep):
0547     dom = parseString("<doc attr='value'><foo/></doc>")
0548     root = dom.documentElement
0549     clone = root.cloneNode(deep)
0550     _testCloneElementCopiesAttributes(
0551         root, clone, "testCloneElement" + (deep and "Deep" or "Shallow"))
0552     # mutilate the original so shared data is detected
0553     root.tagName = root.nodeName = "MODIFIED"
0554     root.setAttribute("attr", "NEW VALUE")
0555     root.setAttribute("added", "VALUE")
0556     return dom, clone
0557 
0558 def _testCloneElementCopiesAttributes(e1, e2, test):
0559     attrs1 = e1.attributes
0560     attrs2 = e2.attributes
0561     keys1 = attrs1.keys()
0562     keys2 = attrs2.keys()
0563     keys1.sort()
0564     keys2.sort()
0565     confirm(keys1 == keys2, "clone of element has same attribute keys")
0566     for i in range(len(keys1)):
0567         a1 = attrs1.item(i)
0568         a2 = attrs2.item(i)
0569         confirm(a1 is not a2
0570                 and a1.value == a2.value
0571                 and a1.nodeValue == a2.nodeValue
0572                 and a1.namespaceURI == a2.namespaceURI
0573                 and a1.localName == a2.localName
0574                 , "clone of attribute node has proper attribute values")
0575         confirm(a2.ownerElement is e2,
0576                 "clone of attribute node correctly owned")
0577 
0578 def testCloneDocumentShallow():
0579     doc = parseString("<?xml version='1.0'?>\n"
0580                       "<!-- comment -->"
0581                       "<!DOCTYPE doc [\n"
0582                       "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
0583                       "]>\n"
0584                       "<doc attr='value'/>")
0585     doc2 = doc.cloneNode(0)
0586     confirm(doc2 is None,
0587             "testCloneDocumentShallow:"
0588             " shallow cloning of documents makes no sense!")
0589 
0590 def testCloneDocumentDeep():
0591     doc = parseString("<?xml version='1.0'?>\n"
0592                       "<!-- comment -->"
0593                       "<!DOCTYPE doc [\n"
0594                       "<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
0595                       "]>\n"
0596                       "<doc attr='value'/>")
0597     doc2 = doc.cloneNode(1)
0598     confirm(not (doc.isSameNode(doc2) or doc2.isSameNode(doc)),
0599             "testCloneDocumentDeep: document objects not distinct")
0600     confirm(len(doc.childNodes) == len(doc2.childNodes),
0601             "testCloneDocumentDeep: wrong number of Document children")
0602     confirm(doc2.documentElement.nodeType == Node.ELEMENT_NODE,
0603             "testCloneDocumentDeep: documentElement not an ELEMENT_NODE")
0604     confirm(doc2.documentElement.ownerDocument.isSameNode(doc2),
0605             "testCloneDocumentDeep: documentElement owner is not new document")
0606     confirm(not doc.documentElement.isSameNode(doc2.documentElement),
0607             "testCloneDocumentDeep: documentElement should not be shared")
0608     if doc.doctype is not None:
0609         # check the doctype iff the original DOM maintained it
0610         confirm(doc2.doctype.nodeType == Node.DOCUMENT_TYPE_NODE,
0611                 "testCloneDocumentDeep: doctype not a DOCUMENT_TYPE_NODE")
0612         confirm(doc2.doctype.ownerDocument.isSameNode(doc2))
0613         confirm(not doc.doctype.isSameNode(doc2.doctype))
0614 
0615 def testCloneDocumentTypeDeepOk():
0616     doctype = create_nonempty_doctype()
0617     clone = doctype.cloneNode(1)
0618     confirm(clone is not None
0619             and clone.nodeName == doctype.nodeName
0620             and clone.name == doctype.name
0621             and clone.publicId == doctype.publicId
0622             and clone.systemId == doctype.systemId
0623             and len(clone.entities) == len(doctype.entities)
0624             and clone.entities.item(len(clone.entities)) is None
0625             and len(clone.notations) == len(doctype.notations)
0626             and clone.notations.item(len(clone.notations)) is None
0627             and len(clone.childNodes) == 0)
0628     for i in range(len(doctype.entities)):
0629         se = doctype.entities.item(i)
0630         ce = clone.entities.item(i)
0631         confirm((not se.isSameNode(ce))
0632                 and (not ce.isSameNode(se))
0633                 and ce.nodeName == se.nodeName
0634                 and ce.notationName == se.notationName
0635                 and ce.publicId == se.publicId
0636                 and ce.systemId == se.systemId
0637                 and ce.encoding == se.encoding
0638                 and ce.actualEncoding == se.actualEncoding
0639                 and ce.version == se.version)
0640     for i in range(len(doctype.notations)):
0641         sn = doctype.notations.item(i)
0642         cn = clone.notations.item(i)
0643         confirm((not sn.isSameNode(cn))
0644                 and (not cn.isSameNode(sn))
0645                 and cn.nodeName == sn.nodeName
0646                 and cn.publicId == sn.publicId
0647                 and cn.systemId == sn.systemId)
0648 
0649 def testCloneDocumentTypeDeepNotOk():
0650     doc = create_doc_with_doctype()
0651     clone = doc.doctype.cloneNode(1)
0652     confirm(clone is None, "testCloneDocumentTypeDeepNotOk")
0653 
0654 def testCloneDocumentTypeShallowOk():
0655     doctype = create_nonempty_doctype()
0656     clone = doctype.cloneNode(0)
0657     confirm(clone is not None
0658             and clone.nodeName == doctype.nodeName
0659             and clone.name == doctype.name
0660             and clone.publicId == doctype.publicId
0661             and clone.systemId == doctype.systemId
0662             and len(clone.entities) == 0
0663             and clone.entities.item(0) is None
0664             and len(clone.notations) == 0
0665             and clone.notations.item(0) is None
0666             and len(clone.childNodes) == 0)
0667 
0668 def testCloneDocumentTypeShallowNotOk():
0669     doc = create_doc_with_doctype()
0670     clone = doc.doctype.cloneNode(0)
0671     confirm(clone is None, "testCloneDocumentTypeShallowNotOk")
0672 
0673 def check_import_document(deep, testName):
0674     doc1 = parseString("<doc/>")
0675     doc2 = parseString("<doc/>")
0676     try:
0677         doc1.importNode(doc2, deep)
0678     except xml.dom.NotSupportedErr:
0679         pass
0680     else:
0681         raise Exception(testName +
0682                         ": expected NotSupportedErr when importing a document")
0683 
0684 def testImportDocumentShallow():
0685     check_import_document(0, "testImportDocumentShallow")
0686 
0687 def testImportDocumentDeep():
0688     check_import_document(1, "testImportDocumentDeep")
0689 
0690 # The tests of DocumentType importing use these helpers to construct
0691 # the documents to work with, since not all DOM builders actually
0692 # create the DocumentType nodes.
0693 
0694 def create_doc_without_doctype(doctype=None):
0695     return getDOMImplementation().createDocument(None, "doc", doctype)
0696 
0697 def create_nonempty_doctype():
0698     doctype = getDOMImplementation().createDocumentType("doc", None, None)
0699     doctype.entities._seq = []
0700     doctype.notations._seq = []
0701     notation = xml.dom.minidom.Notation("my-notation", None,
0702                                         "http://xml.python.org/notations/my")
0703     doctype.notations._seq.append(notation)
0704     entity = xml.dom.minidom.Entity("my-entity", None,
0705                                     "http://xml.python.org/entities/my",
0706                                     "my-notation")
0707     entity.version = "1.0"
0708     entity.encoding = "utf-8"
0709     entity.actualEncoding = "us-ascii"
0710     doctype.entities._seq.append(entity)
0711     return doctype
0712 
0713 def create_doc_with_doctype():
0714     doctype = create_nonempty_doctype()
0715     doc = create_doc_without_doctype(doctype)
0716     doctype.entities.item(0).ownerDocument = doc
0717     doctype.notations.item(0).ownerDocument = doc
0718     return doc
0719 
0720 def testImportDocumentTypeShallow():
0721     src = create_doc_with_doctype()
0722     target = create_doc_without_doctype()
0723     try:
0724         imported = target.importNode(src.doctype, 0)
0725     except xml.dom.NotSupportedErr:
0726         pass
0727     else:
0728         raise Exception(
0729             "testImportDocumentTypeShallow: expected NotSupportedErr")
0730 
0731 def testImportDocumentTypeDeep():
0732     src = create_doc_with_doctype()
0733     target = create_doc_without_doctype()
0734     try:
0735         imported = target.importNode(src.doctype, 1)
0736     except xml.dom.NotSupportedErr:
0737         pass
0738     else:
0739         raise Exception(
0740             "testImportDocumentTypeDeep: expected NotSupportedErr")
0741 
0742 # Testing attribute clones uses a helper, and should always be deep,
0743 # even if the argument to cloneNode is false.
0744 def check_clone_attribute(deep, testName):
0745     doc = parseString("<doc attr='value'/>")
0746     attr = doc.documentElement.getAttributeNode("attr")
0747     assert attr is not None
0748     clone = attr.cloneNode(deep)
0749     confirm(not clone.isSameNode(attr))
0750     confirm(not attr.isSameNode(clone))
0751     confirm(clone.ownerElement is None,
0752             testName + ": ownerElement should be None")
0753     confirm(clone.ownerDocument.isSameNode(attr.ownerDocument),
0754             testName + ": ownerDocument does not match")
0755     confirm(clone.specified,
0756             testName + ": cloned attribute must have specified == True")
0757 
0758 def testCloneAttributeShallow():
0759     check_clone_attribute(0, "testCloneAttributeShallow")
0760 
0761 def testCloneAttributeDeep():
0762     check_clone_attribute(1, "testCloneAttributeDeep")
0763 
0764 def check_clone_pi(deep, testName):
0765     doc = parseString("<?target data?><doc/>")
0766     pi = doc.firstChild
0767     assert pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE
0768     clone = pi.cloneNode(deep)
0769     confirm(clone.target == pi.target
0770             and clone.data == pi.data)
0771 
0772 def testClonePIShallow():
0773     check_clone_pi(0, "testClonePIShallow")
0774 
0775 def testClonePIDeep():
0776     check_clone_pi(1, "testClonePIDeep")
0777 
0778 def testNormalize():
0779     doc = parseString("<doc/>")
0780     root = doc.documentElement
0781     root.appendChild(doc.createTextNode("first"))
0782     root.appendChild(doc.createTextNode("second"))
0783     confirm(len(root.childNodes) == 2
0784             and root.childNodes.length == 2, "testNormalize -- preparation")
0785     doc.normalize()
0786     confirm(len(root.childNodes) == 1
0787             and root.childNodes.length == 1
0788             and root.firstChild is root.lastChild
0789             and root.firstChild.data == "firstsecond"
0790             , "testNormalize -- result")
0791     doc.unlink()
0792 
0793     doc = parseString("<doc/>")
0794     root = doc.documentElement
0795     root.appendChild(doc.createTextNode(""))
0796     doc.normalize()
0797     confirm(len(root.childNodes) == 0
0798             and root.childNodes.length == 0,
0799             "testNormalize -- single empty node removed")
0800     doc.unlink()
0801 
0802 def testSiblings():
0803     doc = parseString("<doc><?pi?>text?<elm/></doc>")
0804     root = doc.documentElement
0805     (pi, text, elm) = root.childNodes
0806 
0807     confirm(pi.nextSibling is text and
0808             pi.previousSibling is None and
0809             text.nextSibling is elm and
0810             text.previousSibling is pi and
0811             elm.nextSibling is None and
0812             elm.previousSibling is text, "testSiblings")
0813 
0814     doc.unlink()
0815 
0816 def testParents():
0817     doc = parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
0818     root = doc.documentElement
0819     elm1 = root.childNodes[0]
0820     (elm2a, elm2b) = elm1.childNodes
0821     elm3 = elm2b.childNodes[0]
0822 
0823     confirm(root.parentNode is doc and
0824             elm1.parentNode is root and
0825             elm2a.parentNode is elm1 and
0826             elm2b.parentNode is elm1 and
0827             elm3.parentNode is elm2b, "testParents")
0828 
0829     doc.unlink()
0830 
0831 def testNodeListItem():
0832     doc = parseString("<doc><e/><e/></doc>")
0833     children = doc.childNodes
0834     docelem = children[0]
0835     confirm(children[0] is children.item(0)
0836             and children.item(1) is None
0837             and docelem.childNodes.item(0) is docelem.childNodes[0]
0838             and docelem.childNodes.item(1) is docelem.childNodes[1]
0839             and docelem.childNodes.item(0).childNodes.item(0) is None,
0840             "test NodeList.item()")
0841     doc.unlink()
0842 
0843 def testSAX2DOM():
0844     from xml.dom import pulldom
0845 
0846     sax2dom = pulldom.SAX2DOM()
0847     sax2dom.startDocument()
0848     sax2dom.startElement("doc", {})
0849     sax2dom.characters("text")
0850     sax2dom.startElement("subelm", {})
0851     sax2dom.characters("text")
0852     sax2dom.endElement("subelm")
0853     sax2dom.characters("text")
0854     sax2dom.endElement("doc")
0855     sax2dom.endDocument()
0856 
0857     doc = sax2dom.document
0858     root = doc.documentElement
0859     (text1, elm1, text2) = root.childNodes
0860     text3 = elm1.childNodes[0]
0861 
0862     confirm(text1.previousSibling is None and
0863             text1.nextSibling is elm1 and
0864             elm1.previousSibling is text1 and
0865             elm1.nextSibling is text2 and
0866             text2.previousSibling is elm1 and
0867             text2.nextSibling is None and
0868             text3.previousSibling is None and
0869             text3.nextSibling is None, "testSAX2DOM - siblings")
0870 
0871     confirm(root.parentNode is doc and
0872             text1.parentNode is root and
0873             elm1.parentNode is root and
0874             text2.parentNode is root and
0875             text3.parentNode is elm1, "testSAX2DOM - parents")
0876 
0877     doc.unlink()
0878 
0879 def testEncodings():
0880     doc = parseString('<foo>&#x20ac;</foo>')
0881     confirm(doc.toxml() == u'<?xml version="1.0" ?>\n<foo>\u20ac</foo>'
0882             and doc.toxml('utf-8') == '<?xml version="1.0" encoding="utf-8"?>\n<foo>\xe2\x82\xac</foo>'
0883             and doc.toxml('iso-8859-15') == '<?xml version="1.0" encoding="iso-8859-15"?>\n<foo>\xa4</foo>',
0884             "testEncodings - encoding EURO SIGN")
0885     doc.unlink()
0886 
0887 class UserDataHandler:
0888     called = 0
0889     def handle(self, operation, key, data, src, dst):
0890         dst.setUserData(key, data + 1, self)
0891         src.setUserData(key, None, None)
0892         self.called = 1
0893 
0894 def testUserData():
0895     dom = Document()
0896     n = dom.createElement('e')
0897     confirm(n.getUserData("foo") is None)
0898     n.setUserData("foo", None, None)
0899     confirm(n.getUserData("foo") is None)
0900     n.setUserData("foo", 12, 12)
0901     n.setUserData("bar", 13, 13)
0902     confirm(n.getUserData("foo") == 12)
0903     confirm(n.getUserData("bar") == 13)
0904     n.setUserData("foo", None, None)
0905     confirm(n.getUserData("foo") is None)
0906     confirm(n.getUserData("bar") == 13)
0907 
0908     handler = UserDataHandler()
0909     n.setUserData("bar", 12, handler)
0910     c = n.cloneNode(1)
0911     confirm(handler.called
0912             and n.getUserData("bar") is None
0913             and c.getUserData("bar") == 13)
0914     n.unlink()
0915     c.unlink()
0916     dom.unlink()
0917 
0918 def testRenameAttribute():
0919     doc = parseString("<doc a='v'/>")
0920     elem = doc.documentElement
0921     attrmap = elem.attributes
0922     attr = elem.attributes['a']
0923 
0924     # Simple renaming
0925     attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "b")
0926     confirm(attr.name == "b"
0927             and attr.nodeName == "b"
0928             and attr.localName is None
0929             and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
0930             and attr.prefix is None
0931             and attr.value == "v"
0932             and elem.getAttributeNode("a") is None
0933             and elem.getAttributeNode("b").isSameNode(attr)
0934             and attrmap["b"].isSameNode(attr)
0935             and attr.ownerDocument.isSameNode(doc)
0936             and attr.ownerElement.isSameNode(elem))
0937 
0938     # Rename to have a namespace, no prefix
0939     attr = doc.renameNode(attr, "http://xml.python.org/ns", "c")
0940     confirm(attr.name == "c"
0941             and attr.nodeName == "c"
0942             and attr.localName == "c"
0943             and attr.namespaceURI == "http://xml.python.org/ns"
0944             and attr.prefix is None
0945             and attr.value == "v"
0946             and elem.getAttributeNode("a") is None
0947             and elem.getAttributeNode("b") is None
0948             and elem.getAttributeNode("c").isSameNode(attr)
0949             and elem.getAttributeNodeNS(
0950                 "http://xml.python.org/ns", "c").isSameNode(attr)
0951             and attrmap["c"].isSameNode(attr)
0952             and attrmap[("http://xml.python.org/ns", "c")].isSameNode(attr))
0953 
0954     # Rename to have a namespace, with prefix
0955     attr = doc.renameNode(attr, "http://xml.python.org/ns2", "p:d")
0956     confirm(attr.name == "p:d"
0957             and attr.nodeName == "p:d"
0958             and attr.localName == "d"
0959             and attr.namespaceURI == "http://xml.python.org/ns2"
0960             and attr.prefix == "p"
0961             and attr.value == "v"
0962             and elem.getAttributeNode("a") is None
0963             and elem.getAttributeNode("b") is None
0964             and elem.getAttributeNode("c") is None
0965             and elem.getAttributeNodeNS(
0966                 "http://xml.python.org/ns", "c") is None
0967             and elem.getAttributeNode("p:d").isSameNode(attr)
0968             and elem.getAttributeNodeNS(
0969                 "http://xml.python.org/ns2", "d").isSameNode(attr)
0970             and attrmap["p:d"].isSameNode(attr)
0971             and attrmap[("http://xml.python.org/ns2", "d")].isSameNode(attr))
0972 
0973     # Rename back to a simple non-NS node
0974     attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "e")
0975     confirm(attr.name == "e"
0976             and attr.nodeName == "e"
0977             and attr.localName is None
0978             and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
0979             and attr.prefix is None
0980             and attr.value == "v"
0981             and elem.getAttributeNode("a") is None
0982             and elem.getAttributeNode("b") is None
0983             and elem.getAttributeNode("c") is None
0984             and elem.getAttributeNode("p:d") is None
0985             and elem.getAttributeNodeNS(
0986                 "http://xml.python.org/ns", "c") is None
0987             and elem.getAttributeNode("e").isSameNode(attr)
0988             and attrmap["e"].isSameNode(attr))
0989 
0990     try:
0991         doc.renameNode(attr, "http://xml.python.org/ns", "xmlns")
0992     except xml.dom.NamespaceErr:
0993         pass
0994     else:
0995         print "expected NamespaceErr"
0996 
0997     checkRenameNodeSharedConstraints(doc, attr)
0998     doc.unlink()
0999 
1000 def testRenameElement():
1001     doc = parseString("<doc/>")
1002     elem = doc.documentElement
1003 
1004     # Simple renaming
1005     elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "a")
1006     confirm(elem.tagName == "a"
1007             and elem.nodeName == "a"
1008             and elem.localName is None
1009             and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
1010             and elem.prefix is None
1011             and elem.ownerDocument.isSameNode(doc))
1012 
1013     # Rename to have a namespace, no prefix
1014     elem = doc.renameNode(elem, "http://xml.python.org/ns", "b")
1015     confirm(elem.tagName == "b"
1016             and elem.nodeName == "b"
1017             and elem.localName == "b"
1018             and elem.namespaceURI == "http://xml.python.org/ns"
1019             and elem.prefix is None
1020             and elem.ownerDocument.isSameNode(doc))
1021 
1022     # Rename to have a namespace, with prefix
1023     elem = doc.renameNode(elem, "http://xml.python.org/ns2", "p:c")
1024     confirm(elem.tagName == "p:c"
1025             and elem.nodeName == "p:c"
1026             and elem.localName == "c"
1027             and elem.namespaceURI == "http://xml.python.org/ns2"
1028             and elem.prefix == "p"
1029             and elem.ownerDocument.isSameNode(doc))
1030 
1031     # Rename back to a simple non-NS node
1032     elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "d")
1033     confirm(elem.tagName == "d"
1034             and elem.nodeName == "d"
1035             and elem.localName is None
1036             and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
1037             and elem.prefix is None
1038             and elem.ownerDocument.isSameNode(doc))
1039 
1040     checkRenameNodeSharedConstraints(doc, elem)
1041     doc.unlink()
1042 
1043 def checkRenameNodeSharedConstraints(doc, node):
1044     # Make sure illegal NS usage is detected:
1045     try:
1046         doc.renameNode(node, "http://xml.python.org/ns", "xmlns:foo")
1047     except xml.dom.NamespaceErr:
1048         pass
1049     else:
1050         print "expected NamespaceErr"
1051 
1052     doc2 = parseString("<doc/>")
1053     try:
1054         doc2.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo")
1055     except xml.dom.WrongDocumentErr:
1056         pass
1057     else:
1058         print "expected WrongDocumentErr"
1059 
1060 def testRenameOther():
1061     # We have to create a comment node explicitly since not all DOM
1062     # builders used with minidom add comments to the DOM.
1063     doc = xml.dom.minidom.getDOMImplementation().createDocument(
1064         xml.dom.EMPTY_NAMESPACE, "e", None)
1065     node = doc.createComment("comment")
1066     try:
1067         doc.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo")
1068     except xml.dom.NotSupportedErr:
1069         pass
1070     else:
1071         print "expected NotSupportedErr when renaming comment node"
1072     doc.unlink()
1073 
1074 def checkWholeText(node, s):
1075     t = node.wholeText
1076     confirm(t == s, "looking for %s, found %s" % (repr(s), repr(t)))
1077 
1078 def testWholeText():
1079     doc = parseString("<doc>a</doc>")
1080     elem = doc.documentElement
1081     text = elem.childNodes[0]
1082     assert text.nodeType == Node.TEXT_NODE
1083 
1084     checkWholeText(text, "a")
1085     elem.appendChild(doc.createTextNode("b"))
1086     checkWholeText(text, "ab")
1087     elem.insertBefore(doc.createCDATASection("c"), text)
1088     checkWholeText(text, "cab")
1089 
1090     # make sure we don't cross other nodes
1091     splitter = doc.createComment("comment")
1092     elem.appendChild(splitter)
1093     text2 = doc.createTextNode("d")
1094     elem.appendChild(text2)
1095     checkWholeText(text, "cab")
1096     checkWholeText(text2, "d")
1097 
1098     x = doc.createElement("x")
1099     elem.replaceChild(x, splitter)
1100     splitter = x
1101     checkWholeText(text, "cab")
1102     checkWholeText(text2, "d")
1103 
1104     x = doc.createProcessingInstruction("y", "z")
1105     elem.replaceChild(x, splitter)
1106     splitter = x
1107     checkWholeText(text, "cab")
1108     checkWholeText(text2, "d")
1109 
1110     elem.removeChild(splitter)
1111     checkWholeText(text, "cabd")
1112     checkWholeText(text2, "cabd")
1113 
1114 def testReplaceWholeText():
1115     def setup():
1116         doc = parseString("<doc>a<e/>d</doc>")
1117         elem = doc.documentElement
1118         text1 = elem.firstChild
1119         text2 = elem.lastChild
1120         splitter = text1.nextSibling
1121         elem.insertBefore(doc.createTextNode("b"), splitter)
1122         elem.insertBefore(doc.createCDATASection("c"), text1)
1123         return doc, elem, text1, splitter, text2
1124 
1125     doc, elem, text1, splitter, text2 = setup()
1126     text = text1.replaceWholeText("new content")
1127     checkWholeText(text, "new content")
1128     checkWholeText(text2, "d")
1129     confirm(len(elem.childNodes) == 3)
1130 
1131     doc, elem, text1, splitter, text2 = setup()
1132     text = text2.replaceWholeText("new content")
1133     checkWholeText(text, "new content")
1134     checkWholeText(text1, "cab")
1135     confirm(len(elem.childNodes) == 5)
1136 
1137     doc, elem, text1, splitter, text2 = setup()
1138     text = text1.replaceWholeText("")
1139     checkWholeText(text2, "d")
1140     confirm(text is None
1141             and len(elem.childNodes) == 2)
1142 
1143 def testSchemaType():
1144     doc = parseString(
1145         "<!DOCTYPE doc [\n"
1146         "  <!ENTITY e1 SYSTEM 'http://xml.python.org/e1'>\n"
1147         "  <!ENTITY e2 SYSTEM 'http://xml.python.org/e2'>\n"
1148         "  <!ATTLIST doc id   ID       #IMPLIED \n"
1149         "                ref  IDREF    #IMPLIED \n"
1150         "                refs IDREFS   #IMPLIED \n"
1151         "                enum (a|b)    #IMPLIED \n"
1152         "                ent  ENTITY   #IMPLIED \n"
1153         "                ents ENTITIES #IMPLIED \n"
1154         "                nm   NMTOKEN  #IMPLIED \n"
1155         "                nms  NMTOKENS #IMPLIED \n"
1156         "                text CDATA    #IMPLIED \n"
1157         "    >\n"
1158         "]><doc id='name' notid='name' text='splat!' enum='b'"
1159         "       ref='name' refs='name name' ent='e1' ents='e1 e2'"
1160         "       nm='123' nms='123 abc' />")
1161     elem = doc.documentElement
1162     # We don't want to rely on any specific loader at this point, so
1163     # just make sure we can get to all the names, and that the
1164     # DTD-based namespace is right.  The names can vary by loader
1165     # since each supports a different level of DTD information.
1166     t = elem.schemaType
1167     confirm(t.name is None
1168             and t.namespace == xml.dom.EMPTY_NAMESPACE)
1169     names = "id notid text enum ref refs ent ents nm nms".split()
1170     for name in names:
1171         a = elem.getAttributeNode(name)
1172         t = a.schemaType
1173         confirm(hasattr(t, "name")
1174                 and t.namespace == xml.dom.EMPTY_NAMESPACE)
1175 
1176 def testSetIdAttribute():
1177     doc = parseString("<doc a1='v' a2='w'/>")
1178     e = doc.documentElement
1179     a1 = e.getAttributeNode("a1")
1180     a2 = e.getAttributeNode("a2")
1181     confirm(doc.getElementById("v") is None
1182             and not a1.isId
1183             and not a2.isId)
1184     e.setIdAttribute("a1")
1185     confirm(e.isSameNode(doc.getElementById("v"))
1186             and a1.isId
1187             and not a2.isId)
1188     e.setIdAttribute("a2")
1189     confirm(e.isSameNode(doc.getElementById("v"))
1190             and e.isSameNode(doc.getElementById("w"))
1191             and a1.isId
1192             and a2.isId)
1193     # replace the a1 node; the new node should *not* be an ID
1194     a3 = doc.createAttribute("a1")
1195     a3.value = "v"
1196     e.setAttributeNode(a3)
1197     confirm(doc.getElementById("v") is None
1198             and e.isSameNode(doc.getElementById("w"))
1199             and not a1.isId
1200             and a2.isId
1201             and not a3.isId)
1202     # renaming an attribute should not affect it's ID-ness:
1203     doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
1204     confirm(e.isSameNode(doc.getElementById("w"))
1205             and a2.isId)
1206 
1207 def testSetIdAttributeNS():
1208     NS1 = "http://xml.python.org/ns1"
1209     NS2 = "http://xml.python.org/ns2"
1210     doc = parseString("<doc"
1211                       " xmlns:ns1='" + NS1 + "'"
1212                       " xmlns:ns2='" + NS2 + "'"
1213                       " ns1:a1='v' ns2:a2='w'/>")
1214     e = doc.documentElement
1215     a1 = e.getAttributeNodeNS(NS1, "a1")
1216     a2 = e.getAttributeNodeNS(NS2, "a2")
1217     confirm(doc.getElementById("v") is None
1218             and not a1.isId
1219             and not a2.isId)
1220     e.setIdAttributeNS(NS1, "a1")
1221     confirm(e.isSameNode(doc.getElementById("v"))
1222             and a1.isId
1223             and not a2.isId)
1224     e.setIdAttributeNS(NS2, "a2")
1225     confirm(e.isSameNode(doc.getElementById("v"))
1226             and e.isSameNode(doc.getElementById("w"))
1227             and a1.isId
1228             and a2.isId)
1229     # replace the a1 node; the new node should *not* be an ID
1230     a3 = doc.createAttributeNS(NS1, "a1")
1231     a3.value = "v"
1232     e.setAttributeNode(a3)
1233     confirm(e.isSameNode(doc.getElementById("w")))
1234     confirm(not a1.isId)
1235     confirm(a2.isId)
1236     confirm(not a3.isId)
1237     confirm(doc.getElementById("v") is None)
1238     # renaming an attribute should not affect it's ID-ness:
1239     doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
1240     confirm(e.isSameNode(doc.getElementById("w"))
1241             and a2.isId)
1242 
1243 def testSetIdAttributeNode():
1244     NS1 = "http://xml.python.org/ns1"
1245     NS2 = "http://xml.python.org/ns2"
1246     doc = parseString("<doc"
1247                       " xmlns:ns1='" + NS1 + "'"
1248                       " xmlns:ns2='" + NS2 + "'"
1249                       " ns1:a1='v' ns2:a2='w'/>")
1250     e = doc.documentElement
1251     a1 = e.getAttributeNodeNS(NS1, "a1")
1252     a2 = e.getAttributeNodeNS(NS2, "a2")
1253     confirm(doc.getElementById("v") is None
1254             and not a1.isId
1255             and not a2.isId)
1256     e.setIdAttributeNode(a1)
1257     confirm(e.isSameNode(doc.getElementById("v"))
1258             and a1.isId
1259             and not a2.isId)
1260     e.setIdAttributeNode(a2)
1261     confirm(e.isSameNode(doc.getElementById("v"))
1262             and e.isSameNode(doc.getElementById("w"))
1263             and a1.isId
1264             and a2.isId)
1265     # replace the a1 node; the new node should *not* be an ID
1266     a3 = doc.createAttributeNS(NS1, "a1")
1267     a3.value = "v"
1268     e.setAttributeNode(a3)
1269     confirm(e.isSameNode(doc.getElementById("w")))
1270     confirm(not a1.isId)
1271     confirm(a2.isId)
1272     confirm(not a3.isId)
1273     confirm(doc.getElementById("v") is None)
1274     # renaming an attribute should not affect it's ID-ness:
1275     doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
1276     confirm(e.isSameNode(doc.getElementById("w"))
1277             and a2.isId)
1278 
1279 def testPickledDocument():
1280     doc = parseString("<?xml version='1.0' encoding='us-ascii'?>\n"
1281                       "<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'"
1282                       " 'http://xml.python.org/system' [\n"
1283                       "  <!ELEMENT e EMPTY>\n"
1284                       "  <!ENTITY ent SYSTEM 'http://xml.python.org/entity'>\n"
1285                       "]><doc attr='value'> text\n"
1286                       "<?pi sample?> <!-- comment --> <e/> </doc>")
1287     s = pickle.dumps(doc)
1288     doc2 = pickle.loads(s)
1289     stack = [(doc, doc2)]
1290     while stack:
1291         n1, n2 = stack.pop()
1292         confirm(n1.nodeType == n2.nodeType
1293                 and len(n1.childNodes) == len(n2.childNodes)
1294                 and n1.nodeName == n2.nodeName
1295                 and not n1.isSameNode(n2)
1296                 and not n2.isSameNode(n1))
1297         if n1.nodeType == Node.DOCUMENT_TYPE_NODE:
1298             len(n1.entities)
1299             len(n2.entities)
1300             len(n1.notations)
1301             len(n2.notations)
1302             confirm(len(n1.entities) == len(n2.entities)
1303                     and len(n1.notations) == len(n2.notations))
1304             for i in range(len(n1.notations)):
1305                 no1 = n1.notations.item(i)
1306                 no2 = n1.notations.item(i)
1307                 confirm(no1.name == no2.name
1308                         and no1.publicId == no2.publicId
1309                         and no1.systemId == no2.systemId)
1310                 statck.append((no1, no2))
1311             for i in range(len(n1.entities)):
1312                 e1 = n1.entities.item(i)
1313                 e2 = n2.entities.item(i)
1314                 confirm(e1.notationName == e2.notationName
1315                         and e1.publicId == e2.publicId
1316                         and e1.systemId == e2.systemId)
1317                 stack.append((e1, e2))
1318         if n1.nodeType != Node.DOCUMENT_NODE:
1319             confirm(n1.ownerDocument.isSameNode(doc)
1320                     and n2.ownerDocument.isSameNode(doc2))
1321         for i in range(len(n1.childNodes)):
1322             stack.append((n1.childNodes[i], n2.childNodes[i]))
1323 
1324 
1325 # --- MAIN PROGRAM
1326 
1327 names = globals().keys()
1328 names.sort()
1329 
1330 failed = []
1331 
1332 try:
1333     Node.allnodes
1334 except AttributeError:
1335     # We don't actually have the minidom from the standard library,
1336     # but are picking up the PyXML version from site-packages.
1337     def check_allnodes():
1338         pass
1339 else:
1340     def check_allnodes():
1341         confirm(len(Node.allnodes) == 0,
1342                 "assertion: len(Node.allnodes) == 0")
1343         if len(Node.allnodes):
1344             print "Garbage left over:"
1345             if verbose:
1346                 print Node.allnodes.items()[0:10]
1347             else:
1348                 # Don't print specific nodes if repeatable results
1349                 # are needed
1350                 print len(Node.allnodes)
1351         Node.allnodes = {}
1352 
1353 for name in names:
1354     if name.startswith("test"):
1355         func = globals()[name]
1356         try:
1357             func()
1358             check_allnodes()
1359         except:
1360             failed.append(name)
1361             print "Test Failed: ", name
1362             sys.stdout.flush()
1363             traceback.print_exception(*sys.exc_info())
1364             print repr(sys.exc_info()[1])
1365             Node.allnodes = {}
1366 
1367 if failed:
1368     print "\n\n\n**** Check for failures in these tests:"
1369     for name in failed:
1370         print "  " + name
1371 

Generated by PyXR 0.9.4
SourceForge.net Logo