cpython/Lib/test/test_minidom.py

540 lines
15 KiB
Python

# test for xml.dom.minidom
from xml.dom.minidom import parse, Node, Document, parseString
from xml.dom import HierarchyRequestErr
import xml.parsers.expat
import os.path
import sys
import traceback
from test_support import verbose
if __name__ == "__main__":
base = sys.argv[0]
else:
base = __file__
tstfile = os.path.join(os.path.dirname(base), "test.xml")
del base
def confirm(test, testname = "Test"):
if test:
print "Passed " + testname
else:
print "Failed " + testname
raise Exception
Node._debug = 1
def testParseFromFile():
from StringIO import StringIO
dom = parse(StringIO(open(tstfile).read()))
dom.unlink()
confirm(isinstance(dom,Document))
def testGetElementsByTagName():
dom = parse(tstfile)
confirm(dom.getElementsByTagName("LI") == \
dom.documentElement.getElementsByTagName("LI"))
dom.unlink()
def testInsertBefore():
dom = parseString("<doc><foo/></doc>")
root = dom.documentElement
elem = root.childNodes[0]
nelem = dom.createElement("element")
root.insertBefore(nelem, elem)
confirm(len(root.childNodes) == 2
and root.childNodes[0] is nelem
and root.childNodes[1] is elem
and root.firstChild is nelem
and root.lastChild is elem
and root.toxml() == "<doc><element/><foo/></doc>"
, "testInsertBefore -- node properly placed in tree")
nelem = dom.createElement("element")
root.insertBefore(nelem, None)
confirm(len(root.childNodes) == 3
and root.childNodes[1] is elem
and root.childNodes[2] is nelem
and root.lastChild is nelem
and nelem.previousSibling is elem
and root.toxml() == "<doc><element/><foo/><element/></doc>"
, "testInsertBefore -- node properly placed in tree")
nelem2 = dom.createElement("bar")
root.insertBefore(nelem2, nelem)
confirm(len(root.childNodes) == 4
and root.childNodes[2] is nelem2
and root.childNodes[3] is nelem
and nelem2.nextSibling is nelem
and nelem.previousSibling is nelem2
and root.toxml() == "<doc><element/><foo/><bar/><element/></doc>"
, "testInsertBefore -- node properly placed in tree")
dom.unlink()
def testAppendChild():
dom = parse(tstfile)
dom.documentElement.appendChild(dom.createComment(u"Hello"))
confirm(dom.documentElement.childNodes[-1].nodeName == "#comment")
confirm(dom.documentElement.childNodes[-1].data == "Hello")
dom.unlink()
def testLegalChildren():
dom = Document()
elem = dom.createElement('element')
text = dom.createTextNode('text')
try: dom.appendChild(text)
except HierarchyRequestErr: pass
else:
print "dom.appendChild didn't raise HierarchyRequestErr"
dom.appendChild(elem)
try: dom.insertBefore(text, elem)
except HierarchyRequestErr: pass
else:
print "dom.appendChild didn't raise HierarchyRequestErr"
try: dom.replaceChild(text, elem)
except HierarchyRequestErr: pass
else:
print "dom.appendChild didn't raise HierarchyRequestErr"
elem.appendChild(text)
dom.unlink()
def testNonZero():
dom = parse(tstfile)
confirm(dom)# should not be zero
dom.appendChild(dom.createComment("foo"))
confirm(not dom.childNodes[-1].childNodes)
dom.unlink()
def testUnlink():
dom = parse(tstfile)
dom.unlink()
def testElement():
dom = Document()
dom.appendChild(dom.createElement("abc"))
confirm(dom.documentElement)
dom.unlink()
def testAAA():
dom = parseString("<abc/>")
el = dom.documentElement
el.setAttribute("spam", "jam2")
confirm(el.toxml() == '<abc spam="jam2"/>', "testAAA")
dom.unlink()
def testAAB():
dom = parseString("<abc/>")
el = dom.documentElement
el.setAttribute("spam", "jam")
el.setAttribute("spam", "jam2")
confirm(el.toxml() == '<abc spam="jam2"/>', "testAAB")
dom.unlink()
def testAddAttr():
dom = Document()
child = dom.appendChild(dom.createElement("abc"))
child.setAttribute("def", "ghi")
confirm(child.getAttribute("def") == "ghi")
confirm(child.attributes["def"].value == "ghi")
child.setAttribute("jkl", "mno")
confirm(child.getAttribute("jkl") == "mno")
confirm(child.attributes["jkl"].value == "mno")
confirm(len(child.attributes) == 2)
child.setAttribute("def", "newval")
confirm(child.getAttribute("def") == "newval")
confirm(child.attributes["def"].value == "newval")
confirm(len(child.attributes) == 2)
dom.unlink()
def testDeleteAttr():
dom = Document()
child = dom.appendChild(dom.createElement("abc"))
confirm(len(child.attributes) == 0)
child.setAttribute("def", "ghi")
confirm(len(child.attributes) == 1)
del child.attributes["def"]
confirm(len(child.attributes) == 0)
dom.unlink()
def testRemoveAttr():
dom = Document()
child = dom.appendChild(dom.createElement("abc"))
child.setAttribute("def", "ghi")
confirm(len(child.attributes) == 1)
child.removeAttribute("def")
confirm(len(child.attributes) == 0)
dom.unlink()
def testRemoveAttrNS():
dom = Document()
child = dom.appendChild(
dom.createElementNS("http://www.python.org", "python:abc"))
child.setAttributeNS("http://www.w3.org", "xmlns:python",
"http://www.python.org")
child.setAttributeNS("http://www.python.org", "python:abcattr", "foo")
confirm(len(child.attributes) == 2)
child.removeAttributeNS("http://www.python.org", "abcattr")
confirm(len(child.attributes) == 1)
dom.unlink()
def testRemoveAttributeNode():
dom = Document()
child = dom.appendChild(dom.createElement("foo"))
child.setAttribute("spam", "jam")
confirm(len(child.attributes) == 1)
node = child.getAttributeNode("spam")
child.removeAttributeNode(node)
confirm(len(child.attributes) == 0)
dom.unlink()
def testChangeAttr():
dom = parseString("<abc/>")
el = dom.documentElement
el.setAttribute("spam", "jam")
confirm(len(el.attributes) == 1)
el.setAttribute("spam", "bam")
confirm(len(el.attributes) == 1)
el.attributes["spam"] = "ham"
confirm(len(el.attributes) == 1)
el.setAttribute("spam2", "bam")
confirm(len(el.attributes) == 2)
el.attributes[ "spam2"] = "bam2"
confirm(len(el.attributes) == 2)
dom.unlink()
def testGetAttrList():
pass
def testGetAttrValues(): pass
def testGetAttrLength(): pass
def testGetAttribute(): pass
def testGetAttributeNS(): pass
def testGetAttributeNode(): pass
def testGetElementsByTagNameNS(): pass
def testGetEmptyNodeListFromElementsByTagNameNS(): pass
def testElementReprAndStr():
dom = Document()
el = dom.appendChild(dom.createElement("abc"))
string1 = repr(el)
string2 = str(el)
confirm(string1 == string2)
dom.unlink()
# commented out until Fredrick's fix is checked in
def _testElementReprAndStrUnicode():
dom = Document()
el = dom.appendChild(dom.createElement(u"abc"))
string1 = repr(el)
string2 = str(el)
confirm(string1 == string2)
dom.unlink()
# commented out until Fredrick's fix is checked in
def _testElementReprAndStrUnicodeNS():
dom = Document()
el = dom.appendChild(
dom.createElementNS(u"http://www.slashdot.org", u"slash:abc"))
string1 = repr(el)
string2 = str(el)
confirm(string1 == string2)
confirm(string1.find("slash:abc") != -1)
dom.unlink()
confirm(len(Node.allnodes) == 0)
def testAttributeRepr():
dom = Document()
el = dom.appendChild(dom.createElement(u"abc"))
node = el.setAttribute("abc", "def")
confirm(str(node) == repr(node))
dom.unlink()
confirm(len(Node.allnodes) == 0)
def testTextNodeRepr(): pass
def testWriteXML():
str = '<?xml version="1.0" ?>\n<a b="c"/>'
dom = parseString(str)
domstr = dom.toxml()
dom.unlink()
confirm(str == domstr)
confirm(len(Node.allnodes) == 0)
def testProcessingInstruction(): pass
def testProcessingInstructionRepr(): pass
def testTextRepr(): pass
def testWriteText(): pass
def testDocumentElement(): pass
def testTooManyDocumentElements():
doc = parseString("<doc/>")
elem = doc.createElement("extra")
try:
doc.appendChild(elem)
except HierarchyRequestErr:
print "Caught expected exception when adding extra document element."
else:
print "Failed to catch expected exception when" \
" adding extra document element."
elem.unlink()
doc.unlink()
def testCreateElementNS(): pass
def testCreateAttributeNS(): pass
def testParse(): pass
def testParseString(): pass
def testComment(): pass
def testAttrListItem(): pass
def testAttrListItems(): pass
def testAttrListItemNS(): pass
def testAttrListKeys(): pass
def testAttrListKeysNS(): pass
def testAttrListValues(): pass
def testAttrListLength(): pass
def testAttrList__getitem__(): pass
def testAttrList__setitem__(): pass
def testSetAttrValueandNodeValue(): pass
def testParseElement(): pass
def testParseAttributes(): pass
def testParseElementNamespaces(): pass
def testParseAttributeNamespaces(): pass
def testParseProcessingInstructions(): pass
def testChildNodes(): pass
def testFirstChild(): pass
def testHasChildNodes(): pass
def testCloneElementShallow():
dom, clone = _setupCloneElement(0)
confirm(len(clone.childNodes) == 0
and clone.parentNode is None
and clone.toxml() == '<doc attr="value"/>'
, "testCloneElementShallow")
dom.unlink()
def testCloneElementDeep():
dom, clone = _setupCloneElement(1)
confirm(len(clone.childNodes) == 1
and clone.parentNode is None
and clone.toxml() == '<doc attr="value"><foo/></doc>'
, "testCloneElementDeep")
dom.unlink()
def _setupCloneElement(deep):
dom = parseString("<doc attr='value'><foo/></doc>")
root = dom.documentElement
clone = root.cloneNode(deep)
_testCloneElementCopiesAttributes(
root, clone, "testCloneElement" + (deep and "Deep" or "Shallow"))
# mutilate the original so shared data is detected
root.tagName = root.nodeName = "MODIFIED"
root.setAttribute("attr", "NEW VALUE")
root.setAttribute("added", "VALUE")
return dom, clone
def _testCloneElementCopiesAttributes(e1, e2, test):
attrs1 = e1.attributes
attrs2 = e2.attributes
keys1 = attrs1.keys()
keys2 = attrs2.keys()
keys1.sort()
keys2.sort()
confirm(keys1 == keys2, "clone of element has same attribute keys")
for i in range(len(keys1)):
a1 = attrs1.item(i)
a2 = attrs2.item(i)
confirm(a1 is not a2
and a1.value == a2.value
and a1.nodeValue == a2.nodeValue
and a1.namespaceURI == a2.namespaceURI
and a1.localName == a2.localName
, "clone of attribute node has proper attribute values")
confirm(a2.ownerElement is e2,
"clone of attribute node correctly owned")
def testCloneDocumentShallow(): pass
def testCloneDocumentDeep(): pass
def testCloneAttributeShallow(): pass
def testCloneAttributeDeep(): pass
def testClonePIShallow(): pass
def testClonePIDeep(): pass
def testNormalize():
doc = parseString("<doc/>")
root = doc.documentElement
root.appendChild(doc.createTextNode("first"))
root.appendChild(doc.createTextNode("second"))
confirm(len(root.childNodes) == 2, "testNormalize -- preparation")
doc.normalize()
confirm(len(root.childNodes) == 1
and root.firstChild is root.lastChild
and root.firstChild.data == "firstsecond"
, "testNormalize -- result")
doc.unlink()
doc = parseString("<doc/>")
root = doc.documentElement
root.appendChild(doc.createTextNode(""))
doc.normalize()
confirm(len(root.childNodes) == 0,
"testNormalize -- single empty node removed")
doc.unlink()
def testSiblings():
doc = parseString("<doc><?pi?>text?<elm/></doc>")
root = doc.documentElement
(pi, text, elm) = root.childNodes
confirm(pi.nextSibling is text and
pi.previousSibling is None and
text.nextSibling is elm and
text.previousSibling is pi and
elm.nextSibling is None and
elm.previousSibling is text, "testSiblings")
doc.unlink()
def testParents():
doc = parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>")
root = doc.documentElement
elm1 = root.childNodes[0]
(elm2a, elm2b) = elm1.childNodes
elm3 = elm2b.childNodes[0]
confirm(root.parentNode is doc and
elm1.parentNode is root and
elm2a.parentNode is elm1 and
elm2b.parentNode is elm1 and
elm3.parentNode is elm2b, "testParents")
doc.unlink()
def testSAX2DOM():
from xml.dom import pulldom
sax2dom = pulldom.SAX2DOM()
sax2dom.startDocument()
sax2dom.startElement("doc", {})
sax2dom.characters("text")
sax2dom.startElement("subelm", {})
sax2dom.characters("text")
sax2dom.endElement("subelm")
sax2dom.characters("text")
sax2dom.endElement("doc")
sax2dom.endDocument()
doc = sax2dom.document
root = doc.documentElement
(text1, elm1, text2) = root.childNodes
text3 = elm1.childNodes[0]
confirm(text1.previousSibling is None and
text1.nextSibling is elm1 and
elm1.previousSibling is text1 and
elm1.nextSibling is text2 and
text2.previousSibling is elm1 and
text2.nextSibling is None and
text3.previousSibling is None and
text3.nextSibling is None, "testSAX2DOM - siblings")
confirm(root.parentNode is doc and
text1.parentNode is root and
elm1.parentNode is root and
text2.parentNode is root and
text3.parentNode is elm1, "testSAX2DOM - parents")
doc.unlink()
# --- MAIN PROGRAM
names = globals().keys()
names.sort()
failed = []
for name in names:
if name.startswith("test"):
func = globals()[name]
try:
func()
print "Test Succeeded", name
confirm(len(Node.allnodes) == 0,
"assertion: len(Node.allnodes) == 0")
if len(Node.allnodes):
print "Garbage left over:"
if verbose:
print Node.allnodes.items()[0:10]
else:
# Don't print specific nodes if repeatable results
# are needed
print len(Node.allnodes)
Node.allnodes = {}
except:
failed.append(name)
print "Test Failed: ", name
sys.stdout.flush()
traceback.print_exception(*sys.exc_info())
print `sys.exc_info()[1]`
Node.allnodes = {}
if failed:
print "\n\n\n**** Check for failures in these tests:"
for name in failed:
print " " + name
print
else:
print "All tests succeeded"
Node.debug = None # Delete debug output collected in a StringIO object
Node._debug = 0 # And reset debug mode