Commit d28fcbc7 authored by Collin Winter's avatar Collin Winter

Consolidate patches #1690164, 1683397, and 1690169, all of which refactor...

Consolidate patches #1690164, 1683397, and 1690169, all of which refactor XML-related test suites. The patches are applied together because they use a common output/xmltests file.
Thanks to Jerry Seutter for all three patches.
parent 366d6262
test_pyexpat
OK.
OK.
OK.
OK.
OK.
OK.
OK.
OK.
OK.
OK.
OK.
OK.
PI:
'xml-stylesheet' 'href="stylesheet.css"'
Comment:
' comment data '
Notation declared: ('notation', None, 'notation.jpeg', None)
Unparsed entity decl:
('unparsed_entity', None, 'entity.file', None, 'notation')
Start element:
'root' {'attr1': 'value1', 'attr2': 'value2\xe1\xbd\x80'}
NS decl:
'myns' 'http://www.python.org/namespace'
Start element:
'http://www.python.org/namespace!subelement' {}
Character data:
'Contents of subelements'
End element:
'http://www.python.org/namespace!subelement'
End of NS decl:
'myns'
Start element:
'sub2' {}
Start of CDATA section
Character data:
'contents of CDATA section'
End of CDATA section
End element:
'sub2'
External entity ref: (None, 'entity.file', None)
End element:
'root'
PI:
u'xml-stylesheet' u'href="stylesheet.css"'
Comment:
u' comment data '
Notation declared: (u'notation', None, u'notation.jpeg', None)
Unparsed entity decl:
(u'unparsed_entity', None, u'entity.file', None, u'notation')
Start element:
u'root' {u'attr1': u'value1', u'attr2': u'value2\u1f40'}
NS decl:
u'myns' u'http://www.python.org/namespace'
Start element:
u'http://www.python.org/namespace!subelement' {}
Character data:
u'Contents of subelements'
End element:
u'http://www.python.org/namespace!subelement'
End of NS decl:
u'myns'
Start element:
u'sub2' {}
Start of CDATA section
Character data:
u'contents of CDATA section'
End of CDATA section
End element:
u'sub2'
External entity ref: (None, u'entity.file', None)
End element:
u'root'
PI:
u'xml-stylesheet' u'href="stylesheet.css"'
Comment:
u' comment data '
Notation declared: (u'notation', None, u'notation.jpeg', None)
Unparsed entity decl:
(u'unparsed_entity', None, u'entity.file', None, u'notation')
Start element:
u'root' {u'attr1': u'value1', u'attr2': u'value2\u1f40'}
NS decl:
u'myns' u'http://www.python.org/namespace'
Start element:
u'http://www.python.org/namespace!subelement' {}
Character data:
u'Contents of subelements'
End element:
u'http://www.python.org/namespace!subelement'
End of NS decl:
u'myns'
Start element:
u'sub2' {}
Start of CDATA section
Character data:
u'contents of CDATA section'
End of CDATA section
End element:
u'sub2'
External entity ref: (None, u'entity.file', None)
End element:
u'root'
Testing constructor for proper handling of namespace_separator values:
Legal values tested o.k.
Caught expected TypeError:
ParserCreate() argument 2 must be string or None, not int
Caught expected ValueError:
namespace_separator must be at most one character, omitted, or None
xmltests
Passed testAAA
Passed setAttribute() sets ownerDocument
Passed setAttribute() sets ownerElement
Test Succeeded testAAA
Passed assertion: len(Node.allnodes) == 0
Passed testAAB
Test Succeeded testAAB
Passed assertion: len(Node.allnodes) == 0
Passed Test
Passed Test
Passed Test
Passed Test
Passed Test
Passed Test
Passed Test
Passed Test
Test Succeeded testAddAttr
Passed assertion: len(Node.allnodes) == 0
Passed Test
Passed Test
Test Succeeded testAppendChild
Passed assertion: len(Node.allnodes) == 0
Passed appendChild(<fragment>)
Test Succeeded testAppendChildFragment
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testAttrListItem
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testAttrListItemNS
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testAttrListItems
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testAttrListKeys
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testAttrListKeysNS
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testAttrListLength
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testAttrListValues
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testAttrList__getitem__
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testAttrList__setitem__
Passed assertion: len(Node.allnodes) == 0
Passed Test
Passed Test
Test Succeeded testAttributeRepr
Passed assertion: len(Node.allnodes) == 0
Passed Test
Passed Test
Passed Test
Passed Test
Passed Test
Test Succeeded testChangeAttr
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testChildNodes
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testCloneAttributeDeep
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testCloneAttributeShallow
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testCloneDocumentDeep
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testCloneDocumentShallow
Passed assertion: len(Node.allnodes) == 0
Passed clone of element has same attribute keys
Passed clone of attribute node has proper attribute values
Passed clone of attribute node correctly owned
Passed testCloneElementDeep
Test Succeeded testCloneElementDeep
Passed assertion: len(Node.allnodes) == 0
Passed clone of element has same attribute keys
Passed clone of attribute node has proper attribute values
Passed clone of attribute node correctly owned
Passed testCloneElementShallow
Test Succeeded testCloneElementShallow
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testClonePIDeep
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testClonePIShallow
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testComment
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testCreateAttributeNS
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testCreateElementNS
Passed assertion: len(Node.allnodes) == 0
Passed Test
Passed Test
Passed Test
Test Succeeded testDeleteAttr
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testDocumentElement
Passed assertion: len(Node.allnodes) == 0
Passed Test
Test Succeeded testElement
Passed assertion: len(Node.allnodes) == 0
Passed Test
Test Succeeded testElementReprAndStr
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testFirstChild
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testGetAttrLength
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testGetAttrList
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testGetAttrValues
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testGetAttribute
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testGetAttributeNS
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testGetAttributeNode
Passed assertion: len(Node.allnodes) == 0
Passed Test
Test Succeeded testGetElementsByTagName
Passed assertion: len(Node.allnodes) == 0
Passed Test
Test Succeeded testGetElementsByTagNameNS
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testGetEmptyNodeListFromElementsByTagNameNS
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testHasChildNodes
Passed assertion: len(Node.allnodes) == 0
Passed testInsertBefore -- node properly placed in tree
Passed testInsertBefore -- node properly placed in tree
Passed testInsertBefore -- node properly placed in tree
Test Succeeded testInsertBefore
Passed assertion: len(Node.allnodes) == 0
Passed insertBefore(<fragment>, None)
Passed insertBefore(<fragment>, orig)
Test Succeeded testInsertBeforeFragment
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testLegalChildren
Passed assertion: len(Node.allnodes) == 0
Passed NamedNodeMap.__setitem__() sets ownerDocument
Passed NamedNodeMap.__setitem__() sets ownerElement
Passed NamedNodeMap.__setitem__() sets value
Passed NamedNodeMap.__setitem__() sets nodeValue
Test Succeeded testNamedNodeMapSetItem
Passed assertion: len(Node.allnodes) == 0
Passed test NodeList.item()
Test Succeeded testNodeListItem
Passed assertion: len(Node.allnodes) == 0
Passed Test
Passed Test
Test Succeeded testNonZero
Passed assertion: len(Node.allnodes) == 0
Passed testNormalize -- preparation
Passed testNormalize -- result
Passed testNormalize -- single empty node removed
Test Succeeded testNormalize
Passed assertion: len(Node.allnodes) == 0
Passed testParents
Test Succeeded testParents
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testParse
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testParseAttributeNamespaces
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testParseAttributes
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testParseElement
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testParseElementNamespaces
Passed assertion: len(Node.allnodes) == 0
Passed Test
Test Succeeded testParseFromFile
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testParseProcessingInstructions
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testParseString
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testProcessingInstruction
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testProcessingInstructionRepr
Passed assertion: len(Node.allnodes) == 0
Passed Test
Passed Test
Test Succeeded testRemoveAttr
Passed assertion: len(Node.allnodes) == 0
Passed Test
Passed Test
Test Succeeded testRemoveAttrNS
Passed assertion: len(Node.allnodes) == 0
Passed Test
Passed Test
Test Succeeded testRemoveAttributeNode
Passed assertion: len(Node.allnodes) == 0
Passed replaceChild(<fragment>)
Test Succeeded testReplaceChildFragment
Passed assertion: len(Node.allnodes) == 0
Passed testSAX2DOM - siblings
Passed testSAX2DOM - parents
Test Succeeded testSAX2DOM
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testSetAttrValueandNodeValue
Passed assertion: len(Node.allnodes) == 0
Passed testSiblings
Test Succeeded testSiblings
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testTextNodeRepr
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testTextRepr
Passed assertion: len(Node.allnodes) == 0
Caught expected exception when adding extra document element.
Test Succeeded testTooManyDocumentElements
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testUnlink
Passed assertion: len(Node.allnodes) == 0
Test Succeeded testWriteText
Passed assertion: len(Node.allnodes) == 0
Passed Test
Passed Test
Test Succeeded testWriteXML
Passed assertion: len(Node.allnodes) == 0
All tests succeeded
OK.
OK.
OK.
OK.
OK.
OK.
OK.
OK.
OK.
OK.
OK.
OK.
PI:
'xml-stylesheet' 'href="stylesheet.css"'
Comment:
' comment data '
Notation declared: ('notation', None, 'notation.jpeg', None)
Unparsed entity decl:
('unparsed_entity', None, 'entity.file', None, 'notation')
Start element:
'root' {'attr1': 'value1', 'attr2': 'value2\xe1\xbd\x80'}
NS decl:
'myns' 'http://www.python.org/namespace'
Start element:
'http://www.python.org/namespace!subelement' {}
Character data:
'Contents of subelements'
End element:
'http://www.python.org/namespace!subelement'
End of NS decl:
'myns'
Start element:
'sub2' {}
Start of CDATA section
Character data:
'contents of CDATA section'
End of CDATA section
End element:
'sub2'
External entity ref: (None, 'entity.file', None)
End element:
'root'
PI:
u'xml-stylesheet' u'href="stylesheet.css"'
Comment:
u' comment data '
Notation declared: (u'notation', None, u'notation.jpeg', None)
Unparsed entity decl:
(u'unparsed_entity', None, u'entity.file', None, u'notation')
Start element:
u'root' {u'attr1': u'value1', u'attr2': u'value2\u1f40'}
NS decl:
u'myns' u'http://www.python.org/namespace'
Start element:
u'http://www.python.org/namespace!subelement' {}
Character data:
u'Contents of subelements'
End element:
u'http://www.python.org/namespace!subelement'
End of NS decl:
u'myns'
Start element:
u'sub2' {}
Start of CDATA section
Character data:
u'contents of CDATA section'
End of CDATA section
End element:
u'sub2'
External entity ref: (None, u'entity.file', None)
End element:
u'root'
PI:
u'xml-stylesheet' u'href="stylesheet.css"'
Comment:
u' comment data '
Notation declared: (u'notation', None, u'notation.jpeg', None)
Unparsed entity decl:
(u'unparsed_entity', None, u'entity.file', None, u'notation')
Start element:
u'root' {u'attr1': u'value1', u'attr2': u'value2\u1f40'}
NS decl:
u'myns' u'http://www.python.org/namespace'
Start element:
u'http://www.python.org/namespace!subelement' {}
Character data:
u'Contents of subelements'
End element:
u'http://www.python.org/namespace!subelement'
End of NS decl:
u'myns'
Start element:
u'sub2' {}
Start of CDATA section
Character data:
u'contents of CDATA section'
End of CDATA section
End element:
u'sub2'
External entity ref: (None, u'entity.file', None)
End element:
u'root'
Testing constructor for proper handling of namespace_separator values:
Legal values tested o.k.
Caught expected TypeError:
ParserCreate() argument 2 must be string or None, not int
Caught expected ValueError:
namespace_separator must be at most one character, omitted, or None
Passed test_attrs_empty
Passed test_attrs_wattr
Passed test_double_quoteattr
Passed test_escape_all
Passed test_escape_basic
Passed test_escape_extra
Passed test_expat_attrs_empty
Passed test_expat_attrs_wattr
Passed test_expat_dtdhandler
Passed test_expat_entityresolver
Passed test_expat_file
Passed test_expat_incomplete
Passed test_expat_incremental
Passed test_expat_incremental_reset
Passed test_expat_inpsource_filename
Passed test_expat_inpsource_location
Passed test_expat_inpsource_stream
Passed test_expat_inpsource_sysid
Passed test_expat_locator_noinfo
Passed test_expat_locator_withinfo
Passed test_expat_nsattrs_empty
Passed test_expat_nsattrs_wattr
Passed test_filter_basic
Passed test_make_parser
Passed test_make_parser2
Passed test_nsattrs_empty
Passed test_nsattrs_wattr
Passed test_quoteattr_basic
Passed test_single_double_quoteattr
Passed test_single_quoteattr
Passed test_xmlgen_attr_escape
Passed test_xmlgen_basic
Passed test_xmlgen_content
Passed test_xmlgen_content_escape
Passed test_xmlgen_ignorable
Passed test_xmlgen_ns
Passed test_xmlgen_pi
37 tests, 0 failures
...@@ -5,7 +5,8 @@ import sys ...@@ -5,7 +5,8 @@ import sys
import pickle import pickle
import traceback import traceback
from StringIO import StringIO from StringIO import StringIO
from test.test_support import verbose from test.test_support import verbose, run_unittest, TestSkipped
import unittest
import xml.dom import xml.dom
import xml.dom.minidom import xml.dom.minidom
...@@ -22,682 +23,9 @@ else: ...@@ -22,682 +23,9 @@ else:
tstfile = os.path.join(os.path.dirname(base), "test"+os.extsep+"xml") tstfile = os.path.join(os.path.dirname(base), "test"+os.extsep+"xml")
del base del base
def confirm(test, testname = "Test"):
if not test:
print "Failed " + testname
raise Exception
def testParseFromFile():
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.length == 2
and root.childNodes[0] is nelem
and root.childNodes.item(0) is nelem
and root.childNodes[1] is elem
and root.childNodes.item(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.length == 3
and root.childNodes[1] is elem
and root.childNodes.item(1) is elem
and root.childNodes[2] is nelem
and root.childNodes.item(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.length == 4
and root.childNodes[2] is nelem2
and root.childNodes.item(2) is nelem2
and root.childNodes[3] is nelem
and root.childNodes.item(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 _create_fragment_test_nodes():
dom = parseString("<doc/>")
orig = dom.createTextNode("original")
c1 = dom.createTextNode("foo")
c2 = dom.createTextNode("bar")
c3 = dom.createTextNode("bat")
dom.documentElement.appendChild(orig)
frag = dom.createDocumentFragment()
frag.appendChild(c1)
frag.appendChild(c2)
frag.appendChild(c3)
return dom, orig, c1, c2, c3, frag
def testInsertBeforeFragment():
dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
dom.documentElement.insertBefore(frag, None)
confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
"insertBefore(<fragment>, None)")
frag.unlink()
dom.unlink()
#
dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
dom.documentElement.insertBefore(frag, orig)
confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3, orig),
"insertBefore(<fragment>, orig)")
frag.unlink()
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 testAppendChildFragment():
dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
dom.documentElement.appendChild(frag)
confirm(tuple(dom.documentElement.childNodes) == (orig, c1, c2, c3),
"appendChild(<fragment>)")
frag.unlink()
dom.unlink()
def testReplaceChildFragment():
dom, orig, c1, c2, c3, frag = _create_fragment_test_nodes()
dom.documentElement.replaceChild(frag, orig)
orig.unlink()
confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3),
"replaceChild(<fragment>)")
frag.unlink()
dom.unlink()
def testLegalChildren():
dom = Document()
elem = dom.createElement('element')
text = dom.createTextNode('text')
try: dom.appendChild(text)
except xml.dom.HierarchyRequestErr: pass
else:
print "dom.appendChild didn't raise HierarchyRequestErr"
dom.appendChild(elem)
try: dom.insertBefore(text, elem)
except xml.dom.HierarchyRequestErr: pass
else:
print "dom.appendChild didn't raise HierarchyRequestErr"
try: dom.replaceChild(text, elem)
except xml.dom.HierarchyRequestErr: pass
else:
print "dom.appendChild didn't raise HierarchyRequestErr"
nodemap = elem.attributes
try: nodemap.setNamedItem(text)
except xml.dom.HierarchyRequestErr: pass
else:
print "NamedNodeMap.setNamedItem didn't raise HierarchyRequestErr"
try: nodemap.setNamedItemNS(text)
except xml.dom.HierarchyRequestErr: pass
else:
print "NamedNodeMap.setNamedItemNS didn't raise HierarchyRequestErr"
elem.appendChild(text)
dom.unlink()
def testNamedNodeMapSetItem():
dom = Document()
elem = dom.createElement('element')
attrs = elem.attributes
attrs["foo"] = "bar"
a = attrs.item(0)
confirm(a.ownerDocument is dom,
"NamedNodeMap.__setitem__() sets ownerDocument")
confirm(a.ownerElement is elem,
"NamedNodeMap.__setitem__() sets ownerElement")
confirm(a.value == "bar",
"NamedNodeMap.__setitem__() sets value")
confirm(a.nodeValue == "bar",
"NamedNodeMap.__setitem__() sets nodeValue")
elem.unlink()
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")
a = el.getAttributeNode("spam")
confirm(a.ownerDocument is dom,
"setAttribute() sets ownerDocument")
confirm(a.ownerElement is dom.documentElement,
"setAttribute() sets ownerElement")
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
and child.getAttributeNode("spam") is None)
dom.unlink()
def testChangeAttr():
dom = parseString("<abc/>")
el = dom.documentElement
el.setAttribute("spam", "jam")
confirm(len(el.attributes) == 1)
el.setAttribute("spam", "bam")
# Set this attribute to be an ID and make sure that doesn't change
# when changing the value:
el.setIdAttribute("spam")
confirm(len(el.attributes) == 1
and el.attributes["spam"].value == "bam"
and el.attributes["spam"].nodeValue == "bam"
and el.getAttribute("spam") == "bam"
and el.getAttributeNode("spam").isId)
el.attributes["spam"] = "ham"
confirm(len(el.attributes) == 1
and el.attributes["spam"].value == "ham"
and el.attributes["spam"].nodeValue == "ham"
and el.getAttribute("spam") == "ham"
and el.attributes["spam"].isId)
el.setAttribute("spam2", "bam")
confirm(len(el.attributes) == 2
and el.attributes["spam"].value == "ham"
and el.attributes["spam"].nodeValue == "ham"
and el.getAttribute("spam") == "ham"
and el.attributes["spam2"].value == "bam"
and el.attributes["spam2"].nodeValue == "bam"
and el.getAttribute("spam2") == "bam")
el.attributes["spam2"] = "bam2"
confirm(len(el.attributes) == 2
and el.attributes["spam"].value == "ham"
and el.attributes["spam"].nodeValue == "ham"
and el.getAttribute("spam") == "ham"
and el.attributes["spam2"].value == "bam2"
and el.attributes["spam2"].nodeValue == "bam2"
and el.getAttribute("spam2") == "bam2")
dom.unlink()
def testGetAttrList():
pass
def testGetAttrValues(): pass
def testGetAttrLength(): pass
def testGetAttribute(): pass
def testGetAttributeNS(): pass
def testGetAttributeNode(): pass
def testGetElementsByTagNameNS():
d="""<foo xmlns:minidom='http://pyxml.sf.net/minidom'>
<minidom:myelem/>
</foo>"""
dom = parseString(d)
elems = dom.getElementsByTagNameNS("http://pyxml.sf.net/minidom", "myelem")
confirm(len(elems) == 1
and elems[0].namespaceURI == "http://pyxml.sf.net/minidom"
and elems[0].localName == "myelem"
and elems[0].prefix == "minidom"
and elems[0].tagName == "minidom:myelem"
and elems[0].nodeName == "minidom:myelem")
dom.unlink()
def get_empty_nodelist_from_elements_by_tagName_ns_helper(doc, nsuri, lname):
nodelist = doc.getElementsByTagNameNS(nsuri, lname)
confirm(len(nodelist) == 0)
def testGetEmptyNodeListFromElementsByTagNameNS():
doc = parseString('<doc/>')
get_empty_nodelist_from_elements_by_tagName_ns_helper(
doc, 'http://xml.python.org/namespaces/a', 'localname')
get_empty_nodelist_from_elements_by_tagName_ns_helper(
doc, '*', 'splat')
get_empty_nodelist_from_elements_by_tagName_ns_helper(
doc, 'http://xml.python.org/namespaces/a', '*')
doc = parseString('<doc xmlns="http://xml.python.org/splat"><e/></doc>')
get_empty_nodelist_from_elements_by_tagName_ns_helper(
doc, "http://xml.python.org/splat", "not-there")
get_empty_nodelist_from_elements_by_tagName_ns_helper(
doc, "*", "not-there")
get_empty_nodelist_from_elements_by_tagName_ns_helper(
doc, "http://somewhere.else.net/not-there", "e")
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()
def testAttributeRepr():
dom = Document()
el = dom.appendChild(dom.createElement(u"abc"))
node = el.setAttribute("abc", "def")
confirm(str(node) == repr(node))
dom.unlink()
def testTextNodeRepr(): pass
def testWriteXML():
str = '<?xml version="1.0" ?><a b="c"/>'
dom = parseString(str)
domstr = dom.toxml()
dom.unlink()
confirm(str == domstr)
def testAltNewline():
str = '<?xml version="1.0" ?>\n<a b="c"/>\n'
dom = parseString(str)
domstr = dom.toprettyxml(newl="\r\n")
dom.unlink()
confirm(domstr == str.replace("\n", "\r\n"))
def testProcessingInstruction():
dom = parseString('<e><?mypi \t\n data \t\n ?></e>')
pi = dom.documentElement.firstChild
confirm(pi.target == "mypi"
and pi.data == "data \t\n "
and pi.nodeName == "mypi"
and pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE
and pi.attributes is None
and not pi.hasChildNodes()
and len(pi.childNodes) == 0
and pi.firstChild is None
and pi.lastChild is None
and pi.localName is None
and pi.namespaceURI == xml.dom.EMPTY_NAMESPACE)
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 xml.dom.HierarchyRequestErr:
pass
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 testRemoveNamedItem():
doc = parseString("<doc a=''/>")
e = doc.documentElement
attrs = e.attributes
a1 = e.getAttributeNode("a")
a2 = attrs.removeNamedItem("a")
confirm(a1.isSameNode(a2))
try:
attrs.removeNamedItem("a")
except xml.dom.NotFoundErr:
pass
def testRemoveNamedItemNS():
doc = parseString("<doc xmlns:a='http://xml.python.org/' a:b=''/>")
e = doc.documentElement
attrs = e.attributes
a1 = e.getAttributeNodeNS("http://xml.python.org/", "b")
a2 = attrs.removeNamedItemNS("http://xml.python.org/", "b")
confirm(a1.isSameNode(a2))
try:
attrs.removeNamedItemNS("http://xml.python.org/", "b")
except xml.dom.NotFoundErr:
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.childNodes.length == 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.childNodes.length == 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():
doc = parseString("<?xml version='1.0'?>\n"
"<!-- comment -->"
"<!DOCTYPE doc [\n"
"<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
"]>\n"
"<doc attr='value'/>")
doc2 = doc.cloneNode(0)
confirm(doc2 is None,
"testCloneDocumentShallow:"
" shallow cloning of documents makes no sense!")
def testCloneDocumentDeep():
doc = parseString("<?xml version='1.0'?>\n"
"<!-- comment -->"
"<!DOCTYPE doc [\n"
"<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
"]>\n"
"<doc attr='value'/>")
doc2 = doc.cloneNode(1)
confirm(not (doc.isSameNode(doc2) or doc2.isSameNode(doc)),
"testCloneDocumentDeep: document objects not distinct")
confirm(len(doc.childNodes) == len(doc2.childNodes),
"testCloneDocumentDeep: wrong number of Document children")
confirm(doc2.documentElement.nodeType == Node.ELEMENT_NODE,
"testCloneDocumentDeep: documentElement not an ELEMENT_NODE")
confirm(doc2.documentElement.ownerDocument.isSameNode(doc2),
"testCloneDocumentDeep: documentElement owner is not new document")
confirm(not doc.documentElement.isSameNode(doc2.documentElement),
"testCloneDocumentDeep: documentElement should not be shared")
if doc.doctype is not None:
# check the doctype iff the original DOM maintained it
confirm(doc2.doctype.nodeType == Node.DOCUMENT_TYPE_NODE,
"testCloneDocumentDeep: doctype not a DOCUMENT_TYPE_NODE")
confirm(doc2.doctype.ownerDocument.isSameNode(doc2))
confirm(not doc.doctype.isSameNode(doc2.doctype))
def testCloneDocumentTypeDeepOk():
doctype = create_nonempty_doctype()
clone = doctype.cloneNode(1)
confirm(clone is not None
and clone.nodeName == doctype.nodeName
and clone.name == doctype.name
and clone.publicId == doctype.publicId
and clone.systemId == doctype.systemId
and len(clone.entities) == len(doctype.entities)
and clone.entities.item(len(clone.entities)) is None
and len(clone.notations) == len(doctype.notations)
and clone.notations.item(len(clone.notations)) is None
and len(clone.childNodes) == 0)
for i in range(len(doctype.entities)):
se = doctype.entities.item(i)
ce = clone.entities.item(i)
confirm((not se.isSameNode(ce))
and (not ce.isSameNode(se))
and ce.nodeName == se.nodeName
and ce.notationName == se.notationName
and ce.publicId == se.publicId
and ce.systemId == se.systemId
and ce.encoding == se.encoding
and ce.actualEncoding == se.actualEncoding
and ce.version == se.version)
for i in range(len(doctype.notations)):
sn = doctype.notations.item(i)
cn = clone.notations.item(i)
confirm((not sn.isSameNode(cn))
and (not cn.isSameNode(sn))
and cn.nodeName == sn.nodeName
and cn.publicId == sn.publicId
and cn.systemId == sn.systemId)
def testCloneDocumentTypeDeepNotOk():
doc = create_doc_with_doctype()
clone = doc.doctype.cloneNode(1)
confirm(clone is None, "testCloneDocumentTypeDeepNotOk")
def testCloneDocumentTypeShallowOk():
doctype = create_nonempty_doctype()
clone = doctype.cloneNode(0)
confirm(clone is not None
and clone.nodeName == doctype.nodeName
and clone.name == doctype.name
and clone.publicId == doctype.publicId
and clone.systemId == doctype.systemId
and len(clone.entities) == 0
and clone.entities.item(0) is None
and len(clone.notations) == 0
and clone.notations.item(0) is None
and len(clone.childNodes) == 0)
def testCloneDocumentTypeShallowNotOk():
doc = create_doc_with_doctype()
clone = doc.doctype.cloneNode(0)
confirm(clone is None, "testCloneDocumentTypeShallowNotOk")
def check_import_document(deep, testName):
doc1 = parseString("<doc/>")
doc2 = parseString("<doc/>")
try:
doc1.importNode(doc2, deep)
except xml.dom.NotSupportedErr:
pass
else:
raise Exception(testName +
": expected NotSupportedErr when importing a document")
def testImportDocumentShallow():
check_import_document(0, "testImportDocumentShallow")
def testImportDocumentDeep():
check_import_document(1, "testImportDocumentDeep")
# The tests of DocumentType importing use these helpers to construct # The tests of DocumentType importing use these helpers to construct
# the documents to work with, since not all DOM builders actually # the documents to work with, since not all DOM builders actually
# create the DocumentType nodes. # create the DocumentType nodes.
def create_doc_without_doctype(doctype=None): def create_doc_without_doctype(doctype=None):
return getDOMImplementation().createDocument(None, "doc", doctype) return getDOMImplementation().createDocument(None, "doc", doctype)
...@@ -724,674 +52,1263 @@ def create_doc_with_doctype(): ...@@ -724,674 +52,1263 @@ def create_doc_with_doctype():
doctype.notations.item(0).ownerDocument = doc doctype.notations.item(0).ownerDocument = doc
return doc return doc
def testImportDocumentTypeShallow(): class MinidomTest(unittest.TestCase):
src = create_doc_with_doctype() def tearDown(self):
target = create_doc_without_doctype() try:
try: Node.allnodes
imported = target.importNode(src.doctype, 0) except AttributeError:
except xml.dom.NotSupportedErr: # We don't actually have the minidom from the standard library,
pass # but are picking up the PyXML version from site-packages.
else: pass
raise Exception( else:
"testImportDocumentTypeShallow: expected NotSupportedErr") self.confirm(len(Node.allnodes) == 0,
"assertion: len(Node.allnodes) == 0")
def testImportDocumentTypeDeep(): if len(Node.allnodes):
src = create_doc_with_doctype() print "Garbage left over:"
target = create_doc_without_doctype() if verbose:
try: print Node.allnodes.items()[0:10]
imported = target.importNode(src.doctype, 1) else:
except xml.dom.NotSupportedErr: # Don't print specific nodes if repeatable results
pass # are needed
else: print len(Node.allnodes)
raise Exception( Node.allnodes = {}
"testImportDocumentTypeDeep: expected NotSupportedErr")
def confirm(self, test, testname = "Test"):
# Testing attribute clones uses a helper, and should always be deep, self.assertTrue(test, testname)
# even if the argument to cloneNode is false.
def check_clone_attribute(deep, testName): def checkWholeText(self, node, s):
doc = parseString("<doc attr='value'/>") t = node.wholeText
attr = doc.documentElement.getAttributeNode("attr") self.confirm(t == s, "looking for %s, found %s" % (repr(s), repr(t)))
assert attr is not None
clone = attr.cloneNode(deep) def testParseFromFile(self):
confirm(not clone.isSameNode(attr)) dom = parse(StringIO(open(tstfile).read()))
confirm(not attr.isSameNode(clone)) dom.unlink()
confirm(clone.ownerElement is None, self.confirm(isinstance(dom,Document))
testName + ": ownerElement should be None")
confirm(clone.ownerDocument.isSameNode(attr.ownerDocument), def testGetElementsByTagName(self):
testName + ": ownerDocument does not match") dom = parse(tstfile)
confirm(clone.specified, self.confirm(dom.getElementsByTagName("LI") == \
testName + ": cloned attribute must have specified == True") dom.documentElement.getElementsByTagName("LI"))
dom.unlink()
def testCloneAttributeShallow():
check_clone_attribute(0, "testCloneAttributeShallow") def testInsertBefore(self):
dom = parseString("<doc><foo/></doc>")
def testCloneAttributeDeep(): root = dom.documentElement
check_clone_attribute(1, "testCloneAttributeDeep") elem = root.childNodes[0]
nelem = dom.createElement("element")
def check_clone_pi(deep, testName): root.insertBefore(nelem, elem)
doc = parseString("<?target data?><doc/>") self.confirm(len(root.childNodes) == 2
pi = doc.firstChild and root.childNodes.length == 2
assert pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE and root.childNodes[0] is nelem
clone = pi.cloneNode(deep) and root.childNodes.item(0) is nelem
confirm(clone.target == pi.target and root.childNodes[1] is elem
and clone.data == pi.data) and root.childNodes.item(1) is elem
and root.firstChild is nelem
def testClonePIShallow(): and root.lastChild is elem
check_clone_pi(0, "testClonePIShallow") and root.toxml() == "<doc><element/><foo/></doc>"
, "testInsertBefore -- node properly placed in tree")
def testClonePIDeep(): nelem = dom.createElement("element")
check_clone_pi(1, "testClonePIDeep") root.insertBefore(nelem, None)
self.confirm(len(root.childNodes) == 3
def testNormalize(): and root.childNodes.length == 3
doc = parseString("<doc/>") and root.childNodes[1] is elem
root = doc.documentElement and root.childNodes.item(1) is elem
root.appendChild(doc.createTextNode("first")) and root.childNodes[2] is nelem
root.appendChild(doc.createTextNode("second")) and root.childNodes.item(2) is nelem
confirm(len(root.childNodes) == 2 and root.lastChild is nelem
and root.childNodes.length == 2, "testNormalize -- preparation") and nelem.previousSibling is elem
doc.normalize() and root.toxml() == "<doc><element/><foo/><element/></doc>"
confirm(len(root.childNodes) == 1 , "testInsertBefore -- node properly placed in tree")
and root.childNodes.length == 1 nelem2 = dom.createElement("bar")
and root.firstChild is root.lastChild root.insertBefore(nelem2, nelem)
and root.firstChild.data == "firstsecond" self.confirm(len(root.childNodes) == 4
, "testNormalize -- result") and root.childNodes.length == 4
doc.unlink() and root.childNodes[2] is nelem2
and root.childNodes.item(2) is nelem2
doc = parseString("<doc/>") and root.childNodes[3] is nelem
root = doc.documentElement and root.childNodes.item(3) is nelem
root.appendChild(doc.createTextNode("")) and nelem2.nextSibling is nelem
doc.normalize() and nelem.previousSibling is nelem2
confirm(len(root.childNodes) == 0 and root.toxml() ==
and root.childNodes.length == 0, "<doc><element/><foo/><bar/><element/></doc>"
"testNormalize -- single empty node removed") , "testInsertBefore -- node properly placed in tree")
doc.unlink() dom.unlink()
def testSiblings(): def _create_fragment_test_nodes(self):
doc = parseString("<doc><?pi?>text?<elm/></doc>") dom = parseString("<doc/>")
root = doc.documentElement orig = dom.createTextNode("original")
(pi, text, elm) = root.childNodes c1 = dom.createTextNode("foo")
c2 = dom.createTextNode("bar")
confirm(pi.nextSibling is text and c3 = dom.createTextNode("bat")
pi.previousSibling is None and dom.documentElement.appendChild(orig)
text.nextSibling is elm and frag = dom.createDocumentFragment()
text.previousSibling is pi and frag.appendChild(c1)
elm.nextSibling is None and frag.appendChild(c2)
elm.previousSibling is text, "testSiblings") frag.appendChild(c3)
return dom, orig, c1, c2, c3, frag
doc.unlink()
def testInsertBeforeFragment(self):
def testParents(): dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes()
doc = parseString("<doc><elm1><elm2/><elm2><elm3/></elm2></elm1></doc>") dom.documentElement.insertBefore(frag, None)
root = doc.documentElement self.confirm(tuple(dom.documentElement.childNodes) ==
elm1 = root.childNodes[0] (orig, c1, c2, c3),
(elm2a, elm2b) = elm1.childNodes "insertBefore(<fragment>, None)")
elm3 = elm2b.childNodes[0] frag.unlink()
dom.unlink()
confirm(root.parentNode is doc and
elm1.parentNode is root and dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes()
elm2a.parentNode is elm1 and dom.documentElement.insertBefore(frag, orig)
elm2b.parentNode is elm1 and self.confirm(tuple(dom.documentElement.childNodes) ==
elm3.parentNode is elm2b, "testParents") (c1, c2, c3, orig),
"insertBefore(<fragment>, orig)")
doc.unlink() frag.unlink()
dom.unlink()
def testNodeListItem():
doc = parseString("<doc><e/><e/></doc>") def testAppendChild(self):
children = doc.childNodes dom = parse(tstfile)
docelem = children[0] dom.documentElement.appendChild(dom.createComment(u"Hello"))
confirm(children[0] is children.item(0) self.confirm(dom.documentElement.childNodes[-1].nodeName == "#comment")
and children.item(1) is None self.confirm(dom.documentElement.childNodes[-1].data == "Hello")
and docelem.childNodes.item(0) is docelem.childNodes[0] dom.unlink()
and docelem.childNodes.item(1) is docelem.childNodes[1]
and docelem.childNodes.item(0).childNodes.item(0) is None, def testAppendChildFragment(self):
"test NodeList.item()") dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes()
doc.unlink() dom.documentElement.appendChild(frag)
self.confirm(tuple(dom.documentElement.childNodes) ==
def testSAX2DOM(): (orig, c1, c2, c3),
from xml.dom import pulldom "appendChild(<fragment>)")
frag.unlink()
sax2dom = pulldom.SAX2DOM() dom.unlink()
sax2dom.startDocument()
sax2dom.startElement("doc", {}) def testReplaceChildFragment(self):
sax2dom.characters("text") dom, orig, c1, c2, c3, frag = self._create_fragment_test_nodes()
sax2dom.startElement("subelm", {}) dom.documentElement.replaceChild(frag, orig)
sax2dom.characters("text") orig.unlink()
sax2dom.endElement("subelm") self.confirm(tuple(dom.documentElement.childNodes) == (c1, c2, c3),
sax2dom.characters("text") "replaceChild(<fragment>)")
sax2dom.endElement("doc") frag.unlink()
sax2dom.endDocument() dom.unlink()
doc = sax2dom.document def testLegalChildren(self):
root = doc.documentElement dom = Document()
(text1, elm1, text2) = root.childNodes elem = dom.createElement('element')
text3 = elm1.childNodes[0] text = dom.createTextNode('text')
self.assertRaises(xml.dom.HierarchyRequestErr, dom.appendChild, text)
confirm(text1.previousSibling is None and
text1.nextSibling is elm1 and dom.appendChild(elem)
elm1.previousSibling is text1 and self.assertRaises(xml.dom.HierarchyRequestErr, dom.insertBefore, text,
elm1.nextSibling is text2 and elem)
text2.previousSibling is elm1 and self.assertRaises(xml.dom.HierarchyRequestErr, dom.replaceChild, text,
text2.nextSibling is None and elem)
text3.previousSibling is None and
text3.nextSibling is None, "testSAX2DOM - siblings") nodemap = elem.attributes
self.assertRaises(xml.dom.HierarchyRequestErr, nodemap.setNamedItem,
confirm(root.parentNode is doc and text)
text1.parentNode is root and self.assertRaises(xml.dom.HierarchyRequestErr, nodemap.setNamedItemNS,
elm1.parentNode is root and text)
text2.parentNode is root and
text3.parentNode is elm1, "testSAX2DOM - parents") elem.appendChild(text)
dom.unlink()
doc.unlink()
def testNamedNodeMapSetItem(self):
def testEncodings(): dom = Document()
doc = parseString('<foo>&#x20ac;</foo>') elem = dom.createElement('element')
confirm(doc.toxml() == u'<?xml version="1.0" ?><foo>\u20ac</foo>' attrs = elem.attributes
and doc.toxml('utf-8') == '<?xml version="1.0" encoding="utf-8"?><foo>\xe2\x82\xac</foo>' attrs["foo"] = "bar"
and doc.toxml('iso-8859-15') == '<?xml version="1.0" encoding="iso-8859-15"?><foo>\xa4</foo>', a = attrs.item(0)
"testEncodings - encoding EURO SIGN") self.confirm(a.ownerDocument is dom,
"NamedNodeMap.__setitem__() sets ownerDocument")
# Verify that character decoding errors throw exceptions instead of crashing self.confirm(a.ownerElement is elem,
try: "NamedNodeMap.__setitem__() sets ownerElement")
doc = parseString('<fran\xe7ais>Comment \xe7a va ? Tr\xe8s bien ?</fran\xe7ais>') self.confirm(a.value == "bar",
except UnicodeDecodeError: "NamedNodeMap.__setitem__() sets value")
pass self.confirm(a.nodeValue == "bar",
else: "NamedNodeMap.__setitem__() sets nodeValue")
print 'parsing with bad encoding should raise a UnicodeDecodeError' elem.unlink()
dom.unlink()
doc.unlink()
def testNonZero(self):
class UserDataHandler: dom = parse(tstfile)
called = 0 self.confirm(dom)# should not be zero
def handle(self, operation, key, data, src, dst): dom.appendChild(dom.createComment("foo"))
dst.setUserData(key, data + 1, self) self.confirm(not dom.childNodes[-1].childNodes)
src.setUserData(key, None, None) dom.unlink()
self.called = 1
def testUnlink(self):
def testUserData(): dom = parse(tstfile)
dom = Document() dom.unlink()
n = dom.createElement('e')
confirm(n.getUserData("foo") is None) def testElement(self):
n.setUserData("foo", None, None) dom = Document()
confirm(n.getUserData("foo") is None) dom.appendChild(dom.createElement("abc"))
n.setUserData("foo", 12, 12) self.confirm(dom.documentElement)
n.setUserData("bar", 13, 13) dom.unlink()
confirm(n.getUserData("foo") == 12)
confirm(n.getUserData("bar") == 13) def testAAA(self):
n.setUserData("foo", None, None) dom = parseString("<abc/>")
confirm(n.getUserData("foo") is None) el = dom.documentElement
confirm(n.getUserData("bar") == 13) el.setAttribute("spam", "jam2")
self.confirm(el.toxml() == '<abc spam="jam2"/>', "testAAA")
handler = UserDataHandler() a = el.getAttributeNode("spam")
n.setUserData("bar", 12, handler) self.confirm(a.ownerDocument is dom,
c = n.cloneNode(1) "setAttribute() sets ownerDocument")
confirm(handler.called self.confirm(a.ownerElement is dom.documentElement,
and n.getUserData("bar") is None "setAttribute() sets ownerElement")
and c.getUserData("bar") == 13) dom.unlink()
n.unlink()
c.unlink() def testAAB(self):
dom.unlink() dom = parseString("<abc/>")
el = dom.documentElement
def testRenameAttribute(): el.setAttribute("spam", "jam")
doc = parseString("<doc a='v'/>") el.setAttribute("spam", "jam2")
elem = doc.documentElement self.confirm(el.toxml() == '<abc spam="jam2"/>', "testAAB")
attrmap = elem.attributes dom.unlink()
attr = elem.attributes['a']
def testAddAttr(self):
# Simple renaming dom = Document()
attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "b") child = dom.appendChild(dom.createElement("abc"))
confirm(attr.name == "b"
and attr.nodeName == "b" child.setAttribute("def", "ghi")
and attr.localName is None self.confirm(child.getAttribute("def") == "ghi")
and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE self.confirm(child.attributes["def"].value == "ghi")
and attr.prefix is None
and attr.value == "v" child.setAttribute("jkl", "mno")
and elem.getAttributeNode("a") is None self.confirm(child.getAttribute("jkl") == "mno")
and elem.getAttributeNode("b").isSameNode(attr) self.confirm(child.attributes["jkl"].value == "mno")
and attrmap["b"].isSameNode(attr)
and attr.ownerDocument.isSameNode(doc) self.confirm(len(child.attributes) == 2)
and attr.ownerElement.isSameNode(elem))
child.setAttribute("def", "newval")
# Rename to have a namespace, no prefix self.confirm(child.getAttribute("def") == "newval")
attr = doc.renameNode(attr, "http://xml.python.org/ns", "c") self.confirm(child.attributes["def"].value == "newval")
confirm(attr.name == "c"
and attr.nodeName == "c" self.confirm(len(child.attributes) == 2)
and attr.localName == "c" dom.unlink()
and attr.namespaceURI == "http://xml.python.org/ns"
and attr.prefix is None def testDeleteAttr(self):
and attr.value == "v" dom = Document()
and elem.getAttributeNode("a") is None child = dom.appendChild(dom.createElement("abc"))
and elem.getAttributeNode("b") is None
and elem.getAttributeNode("c").isSameNode(attr) self.confirm(len(child.attributes) == 0)
and elem.getAttributeNodeNS( child.setAttribute("def", "ghi")
"http://xml.python.org/ns", "c").isSameNode(attr) self.confirm(len(child.attributes) == 1)
and attrmap["c"].isSameNode(attr) del child.attributes["def"]
and attrmap[("http://xml.python.org/ns", "c")].isSameNode(attr)) self.confirm(len(child.attributes) == 0)
dom.unlink()
# Rename to have a namespace, with prefix
attr = doc.renameNode(attr, "http://xml.python.org/ns2", "p:d") def testRemoveAttr(self):
confirm(attr.name == "p:d" dom = Document()
and attr.nodeName == "p:d" child = dom.appendChild(dom.createElement("abc"))
and attr.localName == "d"
and attr.namespaceURI == "http://xml.python.org/ns2" child.setAttribute("def", "ghi")
and attr.prefix == "p" self.confirm(len(child.attributes) == 1)
and attr.value == "v" child.removeAttribute("def")
and elem.getAttributeNode("a") is None self.confirm(len(child.attributes) == 0)
and elem.getAttributeNode("b") is None dom.unlink()
and elem.getAttributeNode("c") is None
and elem.getAttributeNodeNS( def testRemoveAttrNS(self):
"http://xml.python.org/ns", "c") is None dom = Document()
and elem.getAttributeNode("p:d").isSameNode(attr) child = dom.appendChild(
and elem.getAttributeNodeNS( dom.createElementNS("http://www.python.org", "python:abc"))
"http://xml.python.org/ns2", "d").isSameNode(attr) child.setAttributeNS("http://www.w3.org", "xmlns:python",
and attrmap["p:d"].isSameNode(attr) "http://www.python.org")
and attrmap[("http://xml.python.org/ns2", "d")].isSameNode(attr)) child.setAttributeNS("http://www.python.org", "python:abcattr", "foo")
self.confirm(len(child.attributes) == 2)
# Rename back to a simple non-NS node child.removeAttributeNS("http://www.python.org", "abcattr")
attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "e") self.confirm(len(child.attributes) == 1)
confirm(attr.name == "e" dom.unlink()
and attr.nodeName == "e"
and attr.localName is None def testRemoveAttributeNode(self):
and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE dom = Document()
and attr.prefix is None child = dom.appendChild(dom.createElement("foo"))
and attr.value == "v" child.setAttribute("spam", "jam")
and elem.getAttributeNode("a") is None self.confirm(len(child.attributes) == 1)
and elem.getAttributeNode("b") is None node = child.getAttributeNode("spam")
and elem.getAttributeNode("c") is None child.removeAttributeNode(node)
and elem.getAttributeNode("p:d") is None self.confirm(len(child.attributes) == 0
and elem.getAttributeNodeNS( and child.getAttributeNode("spam") is None)
"http://xml.python.org/ns", "c") is None dom.unlink()
and elem.getAttributeNode("e").isSameNode(attr)
and attrmap["e"].isSameNode(attr)) def testChangeAttr(self):
dom = parseString("<abc/>")
try: el = dom.documentElement
doc.renameNode(attr, "http://xml.python.org/ns", "xmlns") el.setAttribute("spam", "jam")
except xml.dom.NamespaceErr: self.confirm(len(el.attributes) == 1)
pass el.setAttribute("spam", "bam")
else: # Set this attribute to be an ID and make sure that doesn't change
print "expected NamespaceErr" # when changing the value:
el.setIdAttribute("spam")
checkRenameNodeSharedConstraints(doc, attr) self.confirm(len(el.attributes) == 1
doc.unlink() and el.attributes["spam"].value == "bam"
and el.attributes["spam"].nodeValue == "bam"
def testRenameElement(): and el.getAttribute("spam") == "bam"
doc = parseString("<doc/>") and el.getAttributeNode("spam").isId)
elem = doc.documentElement el.attributes["spam"] = "ham"
self.confirm(len(el.attributes) == 1
# Simple renaming and el.attributes["spam"].value == "ham"
elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "a") and el.attributes["spam"].nodeValue == "ham"
confirm(elem.tagName == "a" and el.getAttribute("spam") == "ham"
and elem.nodeName == "a" and el.attributes["spam"].isId)
and elem.localName is None el.setAttribute("spam2", "bam")
and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE self.confirm(len(el.attributes) == 2
and elem.prefix is None and el.attributes["spam"].value == "ham"
and elem.ownerDocument.isSameNode(doc)) and el.attributes["spam"].nodeValue == "ham"
and el.getAttribute("spam") == "ham"
# Rename to have a namespace, no prefix and el.attributes["spam2"].value == "bam"
elem = doc.renameNode(elem, "http://xml.python.org/ns", "b") and el.attributes["spam2"].nodeValue == "bam"
confirm(elem.tagName == "b" and el.getAttribute("spam2") == "bam")
and elem.nodeName == "b" el.attributes["spam2"] = "bam2"
and elem.localName == "b" self.confirm(len(el.attributes) == 2
and elem.namespaceURI == "http://xml.python.org/ns" and el.attributes["spam"].value == "ham"
and elem.prefix is None and el.attributes["spam"].nodeValue == "ham"
and elem.ownerDocument.isSameNode(doc)) and el.getAttribute("spam") == "ham"
and el.attributes["spam2"].value == "bam2"
# Rename to have a namespace, with prefix and el.attributes["spam2"].nodeValue == "bam2"
elem = doc.renameNode(elem, "http://xml.python.org/ns2", "p:c") and el.getAttribute("spam2") == "bam2")
confirm(elem.tagName == "p:c" dom.unlink()
and elem.nodeName == "p:c"
and elem.localName == "c" def testGetAttrList(self):
and elem.namespaceURI == "http://xml.python.org/ns2"
and elem.prefix == "p"
and elem.ownerDocument.isSameNode(doc))
# Rename back to a simple non-NS node
elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "d")
confirm(elem.tagName == "d"
and elem.nodeName == "d"
and elem.localName is None
and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
and elem.prefix is None
and elem.ownerDocument.isSameNode(doc))
checkRenameNodeSharedConstraints(doc, elem)
doc.unlink()
def checkRenameNodeSharedConstraints(doc, node):
# Make sure illegal NS usage is detected:
try:
doc.renameNode(node, "http://xml.python.org/ns", "xmlns:foo")
except xml.dom.NamespaceErr:
pass
else:
print "expected NamespaceErr"
doc2 = parseString("<doc/>")
try:
doc2.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo")
except xml.dom.WrongDocumentErr:
pass
else:
print "expected WrongDocumentErr"
def testRenameOther():
# We have to create a comment node explicitly since not all DOM
# builders used with minidom add comments to the DOM.
doc = xml.dom.minidom.getDOMImplementation().createDocument(
xml.dom.EMPTY_NAMESPACE, "e", None)
node = doc.createComment("comment")
try:
doc.renameNode(node, xml.dom.EMPTY_NAMESPACE, "foo")
except xml.dom.NotSupportedErr:
pass pass
else:
print "expected NotSupportedErr when renaming comment node" def testGetAttrValues(self): pass
doc.unlink()
def testGetAttrLength(self): pass
def checkWholeText(node, s):
t = node.wholeText def testGetAttribute(self): pass
confirm(t == s, "looking for %s, found %s" % (repr(s), repr(t)))
def testGetAttributeNS(self): pass
def testWholeText():
doc = parseString("<doc>a</doc>") def testGetAttributeNode(self): pass
elem = doc.documentElement
text = elem.childNodes[0] def testGetElementsByTagNameNS(self):
assert text.nodeType == Node.TEXT_NODE d="""<foo xmlns:minidom='http://pyxml.sf.net/minidom'>
<minidom:myelem/>
checkWholeText(text, "a") </foo>"""
elem.appendChild(doc.createTextNode("b")) dom = parseString(d)
checkWholeText(text, "ab") elems = dom.getElementsByTagNameNS("http://pyxml.sf.net/minidom",
elem.insertBefore(doc.createCDATASection("c"), text) "myelem")
checkWholeText(text, "cab") self.confirm(len(elems) == 1
and elems[0].namespaceURI == "http://pyxml.sf.net/minidom"
# make sure we don't cross other nodes and elems[0].localName == "myelem"
splitter = doc.createComment("comment") and elems[0].prefix == "minidom"
elem.appendChild(splitter) and elems[0].tagName == "minidom:myelem"
text2 = doc.createTextNode("d") and elems[0].nodeName == "minidom:myelem")
elem.appendChild(text2) dom.unlink()
checkWholeText(text, "cab")
checkWholeText(text2, "d") def get_empty_nodelist_from_elements_by_tagName_ns_helper(self, doc, nsuri,
lname):
x = doc.createElement("x") nodelist = doc.getElementsByTagNameNS(nsuri, lname)
elem.replaceChild(x, splitter) self.confirm(len(nodelist) == 0)
splitter = x
checkWholeText(text, "cab") def testGetEmptyNodeListFromElementsByTagNameNS(self):
checkWholeText(text2, "d") doc = parseString('<doc/>')
self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
x = doc.createProcessingInstruction("y", "z") doc, 'http://xml.python.org/namespaces/a', 'localname')
elem.replaceChild(x, splitter) self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
splitter = x doc, '*', 'splat')
checkWholeText(text, "cab") self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
checkWholeText(text2, "d") doc, 'http://xml.python.org/namespaces/a', '*')
elem.removeChild(splitter) doc = parseString('<doc xmlns="http://xml.python.org/splat"><e/></doc>')
checkWholeText(text, "cabd") self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
checkWholeText(text2, "cabd") doc, "http://xml.python.org/splat", "not-there")
self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
def testPatch1094164 (): doc, "*", "not-there")
doc = parseString("<doc><e/></doc>") self.get_empty_nodelist_from_elements_by_tagName_ns_helper(
elem = doc.documentElement doc, "http://somewhere.else.net/not-there", "e")
e = elem.firstChild
confirm(e.parentNode is elem, "Before replaceChild()") def testElementReprAndStr(self):
# Check that replacing a child with itself leaves the tree unchanged dom = Document()
elem.replaceChild(e, e) el = dom.appendChild(dom.createElement("abc"))
confirm(e.parentNode is elem, "After replaceChild()") string1 = repr(el)
string2 = str(el)
self.confirm(string1 == string2)
dom.unlink()
def testReplaceWholeText():
def setup(): def testElementReprAndStrUnicode(self):
doc = parseString("<doc>a<e/>d</doc>") dom = Document()
el = dom.appendChild(dom.createElement(u"abc"))
string1 = repr(el)
string2 = str(el)
self.confirm(string1 == string2)
dom.unlink()
def testElementReprAndStrUnicodeNS(self):
dom = Document()
el = dom.appendChild(
dom.createElementNS(u"http://www.slashdot.org", u"slash:abc"))
string1 = repr(el)
string2 = str(el)
self.confirm(string1 == string2)
self.confirm(string1.find("slash:abc") != -1)
dom.unlink()
def testAttributeRepr(self):
dom = Document()
el = dom.appendChild(dom.createElement(u"abc"))
node = el.setAttribute("abc", "def")
self.confirm(str(node) == repr(node))
dom.unlink()
def testTextNodeRepr(self): pass
def testWriteXML(self):
str = '<?xml version="1.0" ?><a b="c"/>'
dom = parseString(str)
domstr = dom.toxml()
dom.unlink()
self.confirm(str == domstr)
def testAltNewline(self):
str = '<?xml version="1.0" ?>\n<a b="c"/>\n'
dom = parseString(str)
domstr = dom.toprettyxml(newl="\r\n")
dom.unlink()
self.confirm(domstr == str.replace("\n", "\r\n"))
def testProcessingInstruction(self):
dom = parseString('<e><?mypi \t\n data \t\n ?></e>')
pi = dom.documentElement.firstChild
self.confirm(pi.target == "mypi"
and pi.data == "data \t\n "
and pi.nodeName == "mypi"
and pi.nodeType == Node.PROCESSING_INSTRUCTION_NODE
and pi.attributes is None
and not pi.hasChildNodes()
and len(pi.childNodes) == 0
and pi.firstChild is None
and pi.lastChild is None
and pi.localName is None
and pi.namespaceURI == xml.dom.EMPTY_NAMESPACE)
def testProcessingInstructionRepr(self): pass
def testTextRepr(self): pass
def testWriteText(self): pass
def testDocumentElement(self): pass
def testTooManyDocumentElements(self):
doc = parseString("<doc/>")
elem = doc.createElement("extra")
# Should raise an exception when adding an extra document element.
self.assertRaises(xml.dom.HierarchyRequestErr, doc.appendChild, elem)
elem.unlink()
doc.unlink()
def testCreateElementNS(self): pass
def testCreateAttributeNS(self): pass
def testParse(self): pass
def testParseString(self): pass
def testComment(self): pass
def testAttrListItem(self): pass
def testAttrListItems(self): pass
def testAttrListItemNS(self): pass
def testAttrListKeys(self): pass
def testAttrListKeysNS(self): pass
def testRemoveNamedItem(self):
doc = parseString("<doc a=''/>")
e = doc.documentElement
attrs = e.attributes
a1 = e.getAttributeNode("a")
a2 = attrs.removeNamedItem("a")
self.confirm(a1.isSameNode(a2))
self.assertRaises(xml.dom.NotFoundErr, attrs.removeNamedItem, "a")
def testRemoveNamedItemNS(self):
doc = parseString("<doc xmlns:a='http://xml.python.org/' a:b=''/>")
e = doc.documentElement
attrs = e.attributes
a1 = e.getAttributeNodeNS("http://xml.python.org/", "b")
a2 = attrs.removeNamedItemNS("http://xml.python.org/", "b")
self.confirm(a1.isSameNode(a2))
self.assertRaises(xml.dom.NotFoundErr, attrs.removeNamedItemNS,
"http://xml.python.org/", "b")
def testAttrListValues(self): pass
def testAttrListLength(self): pass
def testAttrList__getitem__(self): pass
def testAttrList__setitem__(self): pass
def testSetAttrValueandNodeValue(self): pass
def testParseElement(self): pass
def testParseAttributes(self): pass
def testParseElementNamespaces(self): pass
def testParseAttributeNamespaces(self): pass
def testParseProcessingInstructions(self): pass
def testChildNodes(self): pass
def testFirstChild(self): pass
def testHasChildNodes(self): pass
def _testCloneElementCopiesAttributes(self, e1, e2, test):
attrs1 = e1.attributes
attrs2 = e2.attributes
keys1 = attrs1.keys()
keys2 = attrs2.keys()
keys1.sort()
keys2.sort()
self.confirm(keys1 == keys2, "clone of element has same attribute keys")
for i in range(len(keys1)):
a1 = attrs1.item(i)
a2 = attrs2.item(i)
self.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")
self.confirm(a2.ownerElement is e2,
"clone of attribute node correctly owned")
def _setupCloneElement(self, deep):
dom = parseString("<doc attr='value'><foo/></doc>")
root = dom.documentElement
clone = root.cloneNode(deep)
self._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 testCloneElementShallow(self):
dom, clone = self._setupCloneElement(0)
self.confirm(len(clone.childNodes) == 0
and clone.childNodes.length == 0
and clone.parentNode is None
and clone.toxml() == '<doc attr="value"/>'
, "testCloneElementShallow")
dom.unlink()
def testCloneElementDeep(self):
dom, clone = self._setupCloneElement(1)
self.confirm(len(clone.childNodes) == 1
and clone.childNodes.length == 1
and clone.parentNode is None
and clone.toxml() == '<doc attr="value"><foo/></doc>'
, "testCloneElementDeep")
dom.unlink()
def testCloneDocumentShallow(self):
doc = parseString("<?xml version='1.0'?>\n"
"<!-- comment -->"
"<!DOCTYPE doc [\n"
"<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
"]>\n"
"<doc attr='value'/>")
doc2 = doc.cloneNode(0)
self.confirm(doc2 is None,
"testCloneDocumentShallow:"
" shallow cloning of documents makes no sense!")
def testCloneDocumentDeep(self):
doc = parseString("<?xml version='1.0'?>\n"
"<!-- comment -->"
"<!DOCTYPE doc [\n"
"<!NOTATION notation SYSTEM 'http://xml.python.org/'>\n"
"]>\n"
"<doc attr='value'/>")
doc2 = doc.cloneNode(1)
self.confirm(not (doc.isSameNode(doc2) or doc2.isSameNode(doc)),
"testCloneDocumentDeep: document objects not distinct")
self.confirm(len(doc.childNodes) == len(doc2.childNodes),
"testCloneDocumentDeep: wrong number of Document children")
self.confirm(doc2.documentElement.nodeType == Node.ELEMENT_NODE,
"testCloneDocumentDeep: documentElement not an ELEMENT_NODE")
self.confirm(doc2.documentElement.ownerDocument.isSameNode(doc2),
"testCloneDocumentDeep: documentElement owner is not new document")
self.confirm(not doc.documentElement.isSameNode(doc2.documentElement),
"testCloneDocumentDeep: documentElement should not be shared")
if doc.doctype is not None:
# check the doctype iff the original DOM maintained it
self.confirm(doc2.doctype.nodeType == Node.DOCUMENT_TYPE_NODE,
"testCloneDocumentDeep: doctype not a DOCUMENT_TYPE_NODE")
self.confirm(doc2.doctype.ownerDocument.isSameNode(doc2))
self.confirm(not doc.doctype.isSameNode(doc2.doctype))
def testCloneDocumentTypeDeepOk(self):
doctype = create_nonempty_doctype()
clone = doctype.cloneNode(1)
self.confirm(clone is not None
and clone.nodeName == doctype.nodeName
and clone.name == doctype.name
and clone.publicId == doctype.publicId
and clone.systemId == doctype.systemId
and len(clone.entities) == len(doctype.entities)
and clone.entities.item(len(clone.entities)) is None
and len(clone.notations) == len(doctype.notations)
and clone.notations.item(len(clone.notations)) is None
and len(clone.childNodes) == 0)
for i in range(len(doctype.entities)):
se = doctype.entities.item(i)
ce = clone.entities.item(i)
self.confirm((not se.isSameNode(ce))
and (not ce.isSameNode(se))
and ce.nodeName == se.nodeName
and ce.notationName == se.notationName
and ce.publicId == se.publicId
and ce.systemId == se.systemId
and ce.encoding == se.encoding
and ce.actualEncoding == se.actualEncoding
and ce.version == se.version)
for i in range(len(doctype.notations)):
sn = doctype.notations.item(i)
cn = clone.notations.item(i)
self.confirm((not sn.isSameNode(cn))
and (not cn.isSameNode(sn))
and cn.nodeName == sn.nodeName
and cn.publicId == sn.publicId
and cn.systemId == sn.systemId)
def testCloneDocumentTypeDeepNotOk(self):
doc = create_doc_with_doctype()
clone = doc.doctype.cloneNode(1)
self.confirm(clone is None, "testCloneDocumentTypeDeepNotOk")
def testCloneDocumentTypeShallowOk(self):
doctype = create_nonempty_doctype()
clone = doctype.cloneNode(0)
self.confirm(clone is not None
and clone.nodeName == doctype.nodeName
and clone.name == doctype.name
and clone.publicId == doctype.publicId
and clone.systemId == doctype.systemId
and len(clone.entities) == 0
and clone.entities.item(0) is None
and len(clone.notations) == 0
and clone.notations.item(0) is None
and len(clone.childNodes) == 0)
def testCloneDocumentTypeShallowNotOk(self):
doc = create_doc_with_doctype()
clone = doc.doctype.cloneNode(0)
self.confirm(clone is None, "testCloneDocumentTypeShallowNotOk")
def check_import_document(self, deep, testName):
doc1 = parseString("<doc/>")
doc2 = parseString("<doc/>")
self.assertRaises(xml.dom.NotSupportedErr, doc1.importNode, doc2, deep)
def testImportDocumentShallow(self):
self.check_import_document(0, "testImportDocumentShallow")
def testImportDocumentDeep(self):
self.check_import_document(1, "testImportDocumentDeep")
def testImportDocumentTypeShallow(self):
src = create_doc_with_doctype()
target = create_doc_without_doctype()
self.assertRaises(xml.dom.NotSupportedErr, target.importNode,
src.doctype, 0)
def testImportDocumentTypeDeep(self):
src = create_doc_with_doctype()
target = create_doc_without_doctype()
self.assertRaises(xml.dom.NotSupportedErr, target.importNode,
src.doctype, 1)
# Testing attribute clones uses a helper, and should always be deep,
# even if the argument to cloneNode is false.
def check_clone_attribute(self, deep, testName):
doc = parseString("<doc attr='value'/>")
attr = doc.documentElement.getAttributeNode("attr")
self.failIfEqual(attr, None)
clone = attr.cloneNode(deep)
self.confirm(not clone.isSameNode(attr))
self.confirm(not attr.isSameNode(clone))
self.confirm(clone.ownerElement is None,
testName + ": ownerElement should be None")
self.confirm(clone.ownerDocument.isSameNode(attr.ownerDocument),
testName + ": ownerDocument does not match")
self.confirm(clone.specified,
testName + ": cloned attribute must have specified == True")
def testCloneAttributeShallow(self):
self.check_clone_attribute(0, "testCloneAttributeShallow")
def testCloneAttributeDeep(self):
self.check_clone_attribute(1, "testCloneAttributeDeep")
def check_clone_pi(self, deep, testName):
doc = parseString("<?target data?><doc/>")
pi = doc.firstChild
self.assertEquals(pi.nodeType, Node.PROCESSING_INSTRUCTION_NODE)
clone = pi.cloneNode(deep)
self.confirm(clone.target == pi.target
and clone.data == pi.data)
def testClonePIShallow(self):
self.check_clone_pi(0, "testClonePIShallow")
def testClonePIDeep(self):
self.check_clone_pi(1, "testClonePIDeep")
def testNormalize(self):
doc = parseString("<doc/>")
root = doc.documentElement
root.appendChild(doc.createTextNode("first"))
root.appendChild(doc.createTextNode("second"))
self.confirm(len(root.childNodes) == 2
and root.childNodes.length == 2,
"testNormalize -- preparation")
doc.normalize()
self.confirm(len(root.childNodes) == 1
and root.childNodes.length == 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()
self.confirm(len(root.childNodes) == 0
and root.childNodes.length == 0,
"testNormalize -- single empty node removed")
doc.unlink()
def testSiblings(self):
doc = parseString("<doc><?pi?>text?<elm/></doc>")
root = doc.documentElement
(pi, text, elm) = root.childNodes
self.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(self):
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]
self.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 testNodeListItem(self):
doc = parseString("<doc><e/><e/></doc>")
children = doc.childNodes
docelem = children[0]
self.confirm(children[0] is children.item(0)
and children.item(1) is None
and docelem.childNodes.item(0) is docelem.childNodes[0]
and docelem.childNodes.item(1) is docelem.childNodes[1]
and docelem.childNodes.item(0).childNodes.item(0) is None,
"test NodeList.item()")
doc.unlink()
def testSAX2DOM(self):
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]
self.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")
self.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()
def testEncodings(self):
doc = parseString('<foo>&#x20ac;</foo>')
self.confirm(doc.toxml() == u'<?xml version="1.0" ?><foo>\u20ac</foo>'
and doc.toxml('utf-8') ==
'<?xml version="1.0" encoding="utf-8"?><foo>\xe2\x82\xac</foo>'
and doc.toxml('iso-8859-15') ==
'<?xml version="1.0" encoding="iso-8859-15"?><foo>\xa4</foo>',
"testEncodings - encoding EURO SIGN")
# Verify that character decoding errors throw exceptions instead
# of crashing
self.assertRaises(UnicodeDecodeError, parseString,
'<fran\xe7ais>Comment \xe7a va ? Tr\xe8s bien ?</fran\xe7ais>')
doc.unlink()
class UserDataHandler:
called = 0
def handle(self, operation, key, data, src, dst):
dst.setUserData(key, data + 1, self)
src.setUserData(key, None, None)
self.called = 1
def testUserData(self):
dom = Document()
n = dom.createElement('e')
self.confirm(n.getUserData("foo") is None)
n.setUserData("foo", None, None)
self.confirm(n.getUserData("foo") is None)
n.setUserData("foo", 12, 12)
n.setUserData("bar", 13, 13)
self.confirm(n.getUserData("foo") == 12)
self.confirm(n.getUserData("bar") == 13)
n.setUserData("foo", None, None)
self.confirm(n.getUserData("foo") is None)
self.confirm(n.getUserData("bar") == 13)
handler = self.UserDataHandler()
n.setUserData("bar", 12, handler)
c = n.cloneNode(1)
self.confirm(handler.called
and n.getUserData("bar") is None
and c.getUserData("bar") == 13)
n.unlink()
c.unlink()
dom.unlink()
def checkRenameNodeSharedConstraints(self, doc, node):
# Make sure illegal NS usage is detected:
self.assertRaises(xml.dom.NamespaceErr, doc.renameNode, node,
"http://xml.python.org/ns", "xmlns:foo")
doc2 = parseString("<doc/>")
self.assertRaises(xml.dom.WrongDocumentErr, doc2.renameNode, node,
xml.dom.EMPTY_NAMESPACE, "foo")
def testRenameAttribute(self):
doc = parseString("<doc a='v'/>")
elem = doc.documentElement elem = doc.documentElement
text1 = elem.firstChild attrmap = elem.attributes
text2 = elem.lastChild attr = elem.attributes['a']
splitter = text1.nextSibling
elem.insertBefore(doc.createTextNode("b"), splitter) # Simple renaming
elem.insertBefore(doc.createCDATASection("c"), text1) attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "b")
return doc, elem, text1, splitter, text2 self.confirm(attr.name == "b"
and attr.nodeName == "b"
doc, elem, text1, splitter, text2 = setup() and attr.localName is None
text = text1.replaceWholeText("new content") and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
checkWholeText(text, "new content") and attr.prefix is None
checkWholeText(text2, "d") and attr.value == "v"
confirm(len(elem.childNodes) == 3) and elem.getAttributeNode("a") is None
and elem.getAttributeNode("b").isSameNode(attr)
doc, elem, text1, splitter, text2 = setup() and attrmap["b"].isSameNode(attr)
text = text2.replaceWholeText("new content") and attr.ownerDocument.isSameNode(doc)
checkWholeText(text, "new content") and attr.ownerElement.isSameNode(elem))
checkWholeText(text1, "cab")
confirm(len(elem.childNodes) == 5) # Rename to have a namespace, no prefix
attr = doc.renameNode(attr, "http://xml.python.org/ns", "c")
doc, elem, text1, splitter, text2 = setup() self.confirm(attr.name == "c"
text = text1.replaceWholeText("") and attr.nodeName == "c"
checkWholeText(text2, "d") and attr.localName == "c"
confirm(text is None and attr.namespaceURI == "http://xml.python.org/ns"
and len(elem.childNodes) == 2) and attr.prefix is None
and attr.value == "v"
def testSchemaType(): and elem.getAttributeNode("a") is None
doc = parseString( and elem.getAttributeNode("b") is None
"<!DOCTYPE doc [\n" and elem.getAttributeNode("c").isSameNode(attr)
" <!ENTITY e1 SYSTEM 'http://xml.python.org/e1'>\n" and elem.getAttributeNodeNS(
" <!ENTITY e2 SYSTEM 'http://xml.python.org/e2'>\n" "http://xml.python.org/ns", "c").isSameNode(attr)
" <!ATTLIST doc id ID #IMPLIED \n" and attrmap["c"].isSameNode(attr)
" ref IDREF #IMPLIED \n" and attrmap[("http://xml.python.org/ns", "c")].isSameNode(attr))
" refs IDREFS #IMPLIED \n"
" enum (a|b) #IMPLIED \n" # Rename to have a namespace, with prefix
" ent ENTITY #IMPLIED \n" attr = doc.renameNode(attr, "http://xml.python.org/ns2", "p:d")
" ents ENTITIES #IMPLIED \n" self.confirm(attr.name == "p:d"
" nm NMTOKEN #IMPLIED \n" and attr.nodeName == "p:d"
" nms NMTOKENS #IMPLIED \n" and attr.localName == "d"
" text CDATA #IMPLIED \n" and attr.namespaceURI == "http://xml.python.org/ns2"
" >\n" and attr.prefix == "p"
"]><doc id='name' notid='name' text='splat!' enum='b'" and attr.value == "v"
" ref='name' refs='name name' ent='e1' ents='e1 e2'" and elem.getAttributeNode("a") is None
" nm='123' nms='123 abc' />") and elem.getAttributeNode("b") is None
elem = doc.documentElement and elem.getAttributeNode("c") is None
# We don't want to rely on any specific loader at this point, so and elem.getAttributeNodeNS(
# just make sure we can get to all the names, and that the "http://xml.python.org/ns", "c") is None
# DTD-based namespace is right. The names can vary by loader and elem.getAttributeNode("p:d").isSameNode(attr)
# since each supports a different level of DTD information. and elem.getAttributeNodeNS(
t = elem.schemaType "http://xml.python.org/ns2", "d").isSameNode(attr)
confirm(t.name is None and attrmap["p:d"].isSameNode(attr)
and t.namespace == xml.dom.EMPTY_NAMESPACE) and attrmap[("http://xml.python.org/ns2", "d")].isSameNode(attr))
names = "id notid text enum ref refs ent ents nm nms".split()
for name in names: # Rename back to a simple non-NS node
a = elem.getAttributeNode(name) attr = doc.renameNode(attr, xml.dom.EMPTY_NAMESPACE, "e")
t = a.schemaType self.confirm(attr.name == "e"
confirm(hasattr(t, "name") and attr.nodeName == "e"
and attr.localName is None
and attr.namespaceURI == xml.dom.EMPTY_NAMESPACE
and attr.prefix is None
and attr.value == "v"
and elem.getAttributeNode("a") is None
and elem.getAttributeNode("b") is None
and elem.getAttributeNode("c") is None
and elem.getAttributeNode("p:d") is None
and elem.getAttributeNodeNS(
"http://xml.python.org/ns", "c") is None
and elem.getAttributeNode("e").isSameNode(attr)
and attrmap["e"].isSameNode(attr))
self.assertRaises(xml.dom.NamespaceErr, doc.renameNode, attr,
"http://xml.python.org/ns", "xmlns")
self.checkRenameNodeSharedConstraints(doc, attr)
doc.unlink()
def testRenameElement(self):
doc = parseString("<doc/>")
elem = doc.documentElement
# Simple renaming
elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "a")
self.confirm(elem.tagName == "a"
and elem.nodeName == "a"
and elem.localName is None
and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
and elem.prefix is None
and elem.ownerDocument.isSameNode(doc))
# Rename to have a namespace, no prefix
elem = doc.renameNode(elem, "http://xml.python.org/ns", "b")
self.confirm(elem.tagName == "b"
and elem.nodeName == "b"
and elem.localName == "b"
and elem.namespaceURI == "http://xml.python.org/ns"
and elem.prefix is None
and elem.ownerDocument.isSameNode(doc))
# Rename to have a namespace, with prefix
elem = doc.renameNode(elem, "http://xml.python.org/ns2", "p:c")
self.confirm(elem.tagName == "p:c"
and elem.nodeName == "p:c"
and elem.localName == "c"
and elem.namespaceURI == "http://xml.python.org/ns2"
and elem.prefix == "p"
and elem.ownerDocument.isSameNode(doc))
# Rename back to a simple non-NS node
elem = doc.renameNode(elem, xml.dom.EMPTY_NAMESPACE, "d")
self.confirm(elem.tagName == "d"
and elem.nodeName == "d"
and elem.localName is None
and elem.namespaceURI == xml.dom.EMPTY_NAMESPACE
and elem.prefix is None
and elem.ownerDocument.isSameNode(doc))
self.checkRenameNodeSharedConstraints(doc, elem)
doc.unlink()
def testRenameOther(self):
# We have to create a comment node explicitly since not all DOM
# builders used with minidom add comments to the DOM.
doc = xml.dom.minidom.getDOMImplementation().createDocument(
xml.dom.EMPTY_NAMESPACE, "e", None)
node = doc.createComment("comment")
self.assertRaises(xml.dom.NotSupportedErr, doc.renameNode, node,
xml.dom.EMPTY_NAMESPACE, "foo")
doc.unlink()
def testWholeText(self):
doc = parseString("<doc>a</doc>")
elem = doc.documentElement
text = elem.childNodes[0]
self.assertEquals(text.nodeType, Node.TEXT_NODE)
self.checkWholeText(text, "a")
elem.appendChild(doc.createTextNode("b"))
self.checkWholeText(text, "ab")
elem.insertBefore(doc.createCDATASection("c"), text)
self.checkWholeText(text, "cab")
# make sure we don't cross other nodes
splitter = doc.createComment("comment")
elem.appendChild(splitter)
text2 = doc.createTextNode("d")
elem.appendChild(text2)
self.checkWholeText(text, "cab")
self.checkWholeText(text2, "d")
x = doc.createElement("x")
elem.replaceChild(x, splitter)
splitter = x
self.checkWholeText(text, "cab")
self.checkWholeText(text2, "d")
x = doc.createProcessingInstruction("y", "z")
elem.replaceChild(x, splitter)
splitter = x
self.checkWholeText(text, "cab")
self.checkWholeText(text2, "d")
elem.removeChild(splitter)
self.checkWholeText(text, "cabd")
self.checkWholeText(text2, "cabd")
def testPatch1094164(self):
doc = parseString("<doc><e/></doc>")
elem = doc.documentElement
e = elem.firstChild
self.confirm(e.parentNode is elem, "Before replaceChild()")
# Check that replacing a child with itself leaves the tree unchanged
elem.replaceChild(e, e)
self.confirm(e.parentNode is elem, "After replaceChild()")
def testReplaceWholeText(self):
def setup():
doc = parseString("<doc>a<e/>d</doc>")
elem = doc.documentElement
text1 = elem.firstChild
text2 = elem.lastChild
splitter = text1.nextSibling
elem.insertBefore(doc.createTextNode("b"), splitter)
elem.insertBefore(doc.createCDATASection("c"), text1)
return doc, elem, text1, splitter, text2
doc, elem, text1, splitter, text2 = setup()
text = text1.replaceWholeText("new content")
self.checkWholeText(text, "new content")
self.checkWholeText(text2, "d")
self.confirm(len(elem.childNodes) == 3)
doc, elem, text1, splitter, text2 = setup()
text = text2.replaceWholeText("new content")
self.checkWholeText(text, "new content")
self.checkWholeText(text1, "cab")
self.confirm(len(elem.childNodes) == 5)
doc, elem, text1, splitter, text2 = setup()
text = text1.replaceWholeText("")
self.checkWholeText(text2, "d")
self.confirm(text is None
and len(elem.childNodes) == 2)
def testSchemaType(self):
doc = parseString(
"<!DOCTYPE doc [\n"
" <!ENTITY e1 SYSTEM 'http://xml.python.org/e1'>\n"
" <!ENTITY e2 SYSTEM 'http://xml.python.org/e2'>\n"
" <!ATTLIST doc id ID #IMPLIED \n"
" ref IDREF #IMPLIED \n"
" refs IDREFS #IMPLIED \n"
" enum (a|b) #IMPLIED \n"
" ent ENTITY #IMPLIED \n"
" ents ENTITIES #IMPLIED \n"
" nm NMTOKEN #IMPLIED \n"
" nms NMTOKENS #IMPLIED \n"
" text CDATA #IMPLIED \n"
" >\n"
"]><doc id='name' notid='name' text='splat!' enum='b'"
" ref='name' refs='name name' ent='e1' ents='e1 e2'"
" nm='123' nms='123 abc' />")
elem = doc.documentElement
# We don't want to rely on any specific loader at this point, so
# just make sure we can get to all the names, and that the
# DTD-based namespace is right. The names can vary by loader
# since each supports a different level of DTD information.
t = elem.schemaType
self.confirm(t.name is None
and t.namespace == xml.dom.EMPTY_NAMESPACE) and t.namespace == xml.dom.EMPTY_NAMESPACE)
names = "id notid text enum ref refs ent ents nm nms".split()
def testSetIdAttribute(): for name in names:
doc = parseString("<doc a1='v' a2='w'/>") a = elem.getAttributeNode(name)
e = doc.documentElement t = a.schemaType
a1 = e.getAttributeNode("a1") self.confirm(hasattr(t, "name")
a2 = e.getAttributeNode("a2") and t.namespace == xml.dom.EMPTY_NAMESPACE)
confirm(doc.getElementById("v") is None
and not a1.isId def testSetIdAttribute(self):
and not a2.isId) doc = parseString("<doc a1='v' a2='w'/>")
e.setIdAttribute("a1") e = doc.documentElement
confirm(e.isSameNode(doc.getElementById("v")) a1 = e.getAttributeNode("a1")
and a1.isId a2 = e.getAttributeNode("a2")
and not a2.isId) self.confirm(doc.getElementById("v") is None
e.setIdAttribute("a2") and not a1.isId
confirm(e.isSameNode(doc.getElementById("v")) and not a2.isId)
and e.isSameNode(doc.getElementById("w")) e.setIdAttribute("a1")
and a1.isId self.confirm(e.isSameNode(doc.getElementById("v"))
and a2.isId) and a1.isId
# replace the a1 node; the new node should *not* be an ID and not a2.isId)
a3 = doc.createAttribute("a1") e.setIdAttribute("a2")
a3.value = "v" self.confirm(e.isSameNode(doc.getElementById("v"))
e.setAttributeNode(a3) and e.isSameNode(doc.getElementById("w"))
confirm(doc.getElementById("v") is None and a1.isId
and e.isSameNode(doc.getElementById("w")) and a2.isId)
and not a1.isId # replace the a1 node; the new node should *not* be an ID
and a2.isId a3 = doc.createAttribute("a1")
and not a3.isId) a3.value = "v"
# renaming an attribute should not affect its ID-ness: e.setAttributeNode(a3)
doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an") self.confirm(doc.getElementById("v") is None
confirm(e.isSameNode(doc.getElementById("w")) and e.isSameNode(doc.getElementById("w"))
and a2.isId) and not a1.isId
and a2.isId
def testSetIdAttributeNS(): and not a3.isId)
NS1 = "http://xml.python.org/ns1" # renaming an attribute should not affect its ID-ness:
NS2 = "http://xml.python.org/ns2" doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
doc = parseString("<doc" self.confirm(e.isSameNode(doc.getElementById("w"))
" xmlns:ns1='" + NS1 + "'" and a2.isId)
" xmlns:ns2='" + NS2 + "'"
" ns1:a1='v' ns2:a2='w'/>") def testSetIdAttributeNS(self):
e = doc.documentElement NS1 = "http://xml.python.org/ns1"
a1 = e.getAttributeNodeNS(NS1, "a1") NS2 = "http://xml.python.org/ns2"
a2 = e.getAttributeNodeNS(NS2, "a2") doc = parseString("<doc"
confirm(doc.getElementById("v") is None " xmlns:ns1='" + NS1 + "'"
and not a1.isId " xmlns:ns2='" + NS2 + "'"
and not a2.isId) " ns1:a1='v' ns2:a2='w'/>")
e.setIdAttributeNS(NS1, "a1") e = doc.documentElement
confirm(e.isSameNode(doc.getElementById("v")) a1 = e.getAttributeNodeNS(NS1, "a1")
and a1.isId a2 = e.getAttributeNodeNS(NS2, "a2")
and not a2.isId) self.confirm(doc.getElementById("v") is None
e.setIdAttributeNS(NS2, "a2") and not a1.isId
confirm(e.isSameNode(doc.getElementById("v")) and not a2.isId)
and e.isSameNode(doc.getElementById("w")) e.setIdAttributeNS(NS1, "a1")
and a1.isId self.confirm(e.isSameNode(doc.getElementById("v"))
and a2.isId) and a1.isId
# replace the a1 node; the new node should *not* be an ID and not a2.isId)
a3 = doc.createAttributeNS(NS1, "a1") e.setIdAttributeNS(NS2, "a2")
a3.value = "v" self.confirm(e.isSameNode(doc.getElementById("v"))
e.setAttributeNode(a3) and e.isSameNode(doc.getElementById("w"))
confirm(e.isSameNode(doc.getElementById("w"))) and a1.isId
confirm(not a1.isId) and a2.isId)
confirm(a2.isId) # replace the a1 node; the new node should *not* be an ID
confirm(not a3.isId) a3 = doc.createAttributeNS(NS1, "a1")
confirm(doc.getElementById("v") is None) a3.value = "v"
# renaming an attribute should not affect its ID-ness: e.setAttributeNode(a3)
doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an") self.confirm(e.isSameNode(doc.getElementById("w")))
confirm(e.isSameNode(doc.getElementById("w")) self.confirm(not a1.isId)
and a2.isId) self.confirm(a2.isId)
self.confirm(not a3.isId)
def testSetIdAttributeNode(): self.confirm(doc.getElementById("v") is None)
NS1 = "http://xml.python.org/ns1" # renaming an attribute should not affect its ID-ness:
NS2 = "http://xml.python.org/ns2" doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
doc = parseString("<doc" self.confirm(e.isSameNode(doc.getElementById("w"))
" xmlns:ns1='" + NS1 + "'" and a2.isId)
" xmlns:ns2='" + NS2 + "'"
" ns1:a1='v' ns2:a2='w'/>") def testSetIdAttributeNode(self):
e = doc.documentElement NS1 = "http://xml.python.org/ns1"
a1 = e.getAttributeNodeNS(NS1, "a1") NS2 = "http://xml.python.org/ns2"
a2 = e.getAttributeNodeNS(NS2, "a2") doc = parseString("<doc"
confirm(doc.getElementById("v") is None " xmlns:ns1='" + NS1 + "'"
and not a1.isId " xmlns:ns2='" + NS2 + "'"
and not a2.isId) " ns1:a1='v' ns2:a2='w'/>")
e.setIdAttributeNode(a1) e = doc.documentElement
confirm(e.isSameNode(doc.getElementById("v")) a1 = e.getAttributeNodeNS(NS1, "a1")
and a1.isId a2 = e.getAttributeNodeNS(NS2, "a2")
and not a2.isId) self.confirm(doc.getElementById("v") is None
e.setIdAttributeNode(a2) and not a1.isId
confirm(e.isSameNode(doc.getElementById("v")) and not a2.isId)
and e.isSameNode(doc.getElementById("w")) e.setIdAttributeNode(a1)
and a1.isId self.confirm(e.isSameNode(doc.getElementById("v"))
and a2.isId) and a1.isId
# replace the a1 node; the new node should *not* be an ID and not a2.isId)
a3 = doc.createAttributeNS(NS1, "a1") e.setIdAttributeNode(a2)
a3.value = "v" self.confirm(e.isSameNode(doc.getElementById("v"))
e.setAttributeNode(a3) and e.isSameNode(doc.getElementById("w"))
confirm(e.isSameNode(doc.getElementById("w"))) and a1.isId
confirm(not a1.isId) and a2.isId)
confirm(a2.isId) # replace the a1 node; the new node should *not* be an ID
confirm(not a3.isId) a3 = doc.createAttributeNS(NS1, "a1")
confirm(doc.getElementById("v") is None) a3.value = "v"
# renaming an attribute should not affect its ID-ness: e.setAttributeNode(a3)
doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an") self.confirm(e.isSameNode(doc.getElementById("w")))
confirm(e.isSameNode(doc.getElementById("w")) self.confirm(not a1.isId)
and a2.isId) self.confirm(a2.isId)
self.confirm(not a3.isId)
def testPickledDocument(): self.confirm(doc.getElementById("v") is None)
doc = parseString("<?xml version='1.0' encoding='us-ascii'?>\n" # renaming an attribute should not affect its ID-ness:
"<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'" doc.renameNode(a2, xml.dom.EMPTY_NAMESPACE, "an")
" 'http://xml.python.org/system' [\n" self.confirm(e.isSameNode(doc.getElementById("w"))
" <!ELEMENT e EMPTY>\n" and a2.isId)
" <!ENTITY ent SYSTEM 'http://xml.python.org/entity'>\n"
"]><doc attr='value'> text\n" def testPickledDocument(self):
"<?pi sample?> <!-- comment --> <e/> </doc>") doc = parseString("<?xml version='1.0' encoding='us-ascii'?>\n"
s = pickle.dumps(doc) "<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'"
doc2 = pickle.loads(s) " 'http://xml.python.org/system' [\n"
stack = [(doc, doc2)] " <!ELEMENT e EMPTY>\n"
while stack: " <!ENTITY ent SYSTEM 'http://xml.python.org/entity'>\n"
n1, n2 = stack.pop() "]><doc attr='value'> text\n"
confirm(n1.nodeType == n2.nodeType "<?pi sample?> <!-- comment --> <e/> </doc>")
and len(n1.childNodes) == len(n2.childNodes) s = pickle.dumps(doc)
and n1.nodeName == n2.nodeName doc2 = pickle.loads(s)
and not n1.isSameNode(n2) stack = [(doc, doc2)]
and not n2.isSameNode(n1)) while stack:
if n1.nodeType == Node.DOCUMENT_TYPE_NODE: n1, n2 = stack.pop()
len(n1.entities) self.confirm(n1.nodeType == n2.nodeType
len(n2.entities) and len(n1.childNodes) == len(n2.childNodes)
len(n1.notations) and n1.nodeName == n2.nodeName
len(n2.notations) and not n1.isSameNode(n2)
confirm(len(n1.entities) == len(n2.entities) and not n2.isSameNode(n1))
and len(n1.notations) == len(n2.notations)) if n1.nodeType == Node.DOCUMENT_TYPE_NODE:
for i in range(len(n1.notations)): len(n1.entities)
no1 = n1.notations.item(i) len(n2.entities)
no2 = n1.notations.item(i) len(n1.notations)
confirm(no1.name == no2.name len(n2.notations)
and no1.publicId == no2.publicId self.confirm(len(n1.entities) == len(n2.entities)
and no1.systemId == no2.systemId) and len(n1.notations) == len(n2.notations))
statck.append((no1, no2)) for i in range(len(n1.notations)):
for i in range(len(n1.entities)): no1 = n1.notations.item(i)
e1 = n1.entities.item(i) no2 = n1.notations.item(i)
e2 = n2.entities.item(i) self.confirm(no1.name == no2.name
confirm(e1.notationName == e2.notationName and no1.publicId == no2.publicId
and e1.publicId == e2.publicId and no1.systemId == no2.systemId)
and e1.systemId == e2.systemId) statck.append((no1, no2))
stack.append((e1, e2)) for i in range(len(n1.entities)):
if n1.nodeType != Node.DOCUMENT_NODE: e1 = n1.entities.item(i)
confirm(n1.ownerDocument.isSameNode(doc) e2 = n2.entities.item(i)
and n2.ownerDocument.isSameNode(doc2)) self.confirm(e1.notationName == e2.notationName
for i in range(len(n1.childNodes)): and e1.publicId == e2.publicId
stack.append((n1.childNodes[i], n2.childNodes[i])) and e1.systemId == e2.systemId)
stack.append((e1, e2))
if n1.nodeType != Node.DOCUMENT_NODE:
# --- MAIN PROGRAM self.confirm(n1.ownerDocument.isSameNode(doc)
and n2.ownerDocument.isSameNode(doc2))
names = globals().keys() for i in range(len(n1.childNodes)):
names.sort() stack.append((n1.childNodes[i], n2.childNodes[i]))
failed = [] def test_main():
run_unittest(MinidomTest)
try:
Node.allnodes if __name__ == "__main__":
except AttributeError: test_main()
# We don't actually have the minidom from the standard library,
# but are picking up the PyXML version from site-packages.
def check_allnodes():
pass
else:
def check_allnodes():
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 = {}
for name in names:
if name.startswith("test"):
func = globals()[name]
try:
func()
check_allnodes()
except:
failed.append(name)
print "Test Failed: ", name
sys.stdout.flush()
traceback.print_exception(*sys.exc_info())
print repr(sys.exc_info()[1])
Node.allnodes = {}
if failed:
print "\n\n\n**** Check for failures in these tests:"
for name in failed:
print " " + name
# Very simple test - Parse a file and print what happens
# XXX TypeErrors on calling handlers, or on bad return values from a # XXX TypeErrors on calling handlers, or on bad return values from a
# handler, are obscure and unhelpful. # handler, are obscure and unhelpful.
import StringIO
import unittest
import pyexpat import pyexpat
from xml.parsers import expat from xml.parsers import expat
from test.test_support import sortdict, TestFailed from test.test_support import sortdict, run_unittest
class SetAttributeTest(unittest.TestCase):
def setUp(self):
self.parser = expat.ParserCreate(namespace_separator='!')
self.set_get_pairs = [
[0, 0],
[1, 1],
[2, 1],
[0, 0],
]
def test_returns_unicode(self):
for x, y in self.set_get_pairs:
self.parser.returns_unicode = x
self.assertEquals(self.parser.returns_unicode, y)
def test_ordered_attributes(self):
for x, y in self.set_get_pairs:
self.parser.ordered_attributes = x
self.assertEquals(self.parser.ordered_attributes, y)
def test_specified_attributes(self):
for x, y in self.set_get_pairs:
self.parser.specified_attributes = x
self.assertEquals(self.parser.specified_attributes, y)
class Outputter:
def StartElementHandler(self, name, attrs):
print 'Start element:\n\t', repr(name), sortdict(attrs)
def EndElementHandler(self, name):
print 'End element:\n\t', repr(name)
def CharacterDataHandler(self, data):
data = data.strip()
if data:
print 'Character data:'
print '\t', repr(data)
def ProcessingInstructionHandler(self, target, data):
print 'PI:\n\t', repr(target), repr(data)
def StartNamespaceDeclHandler(self, prefix, uri):
print 'NS decl:\n\t', repr(prefix), repr(uri)
def EndNamespaceDeclHandler(self, prefix):
print 'End of NS decl:\n\t', repr(prefix)
def StartCdataSectionHandler(self):
print 'Start of CDATA section'
def EndCdataSectionHandler(self):
print 'End of CDATA section'
def CommentHandler(self, text):
print 'Comment:\n\t', repr(text)
def NotationDeclHandler(self, *args):
name, base, sysid, pubid = args
print 'Notation declared:', args
def UnparsedEntityDeclHandler(self, *args):
entityName, base, systemId, publicId, notationName = args
print 'Unparsed entity decl:\n\t', args
def NotStandaloneHandler(self, userData):
print 'Not standalone'
return 1
def ExternalEntityRefHandler(self, *args):
context, base, sysId, pubId = args
print 'External entity ref:', args[1:]
return 1
def DefaultHandler(self, userData):
pass
def DefaultHandlerExpand(self, userData):
pass
def confirm(ok):
if ok:
print "OK."
else:
print "Not OK."
out = Outputter()
parser = expat.ParserCreate(namespace_separator='!')
# Test getting/setting returns_unicode
parser.returns_unicode = 0; confirm(parser.returns_unicode == 0)
parser.returns_unicode = 1; confirm(parser.returns_unicode == 1)
parser.returns_unicode = 2; confirm(parser.returns_unicode == 1)
parser.returns_unicode = 0; confirm(parser.returns_unicode == 0)
# Test getting/setting ordered_attributes
parser.ordered_attributes = 0; confirm(parser.ordered_attributes == 0)
parser.ordered_attributes = 1; confirm(parser.ordered_attributes == 1)
parser.ordered_attributes = 2; confirm(parser.ordered_attributes == 1)
parser.ordered_attributes = 0; confirm(parser.ordered_attributes == 0)
# Test getting/setting specified_attributes
parser.specified_attributes = 0; confirm(parser.specified_attributes == 0)
parser.specified_attributes = 1; confirm(parser.specified_attributes == 1)
parser.specified_attributes = 2; confirm(parser.specified_attributes == 1)
parser.specified_attributes = 0; confirm(parser.specified_attributes == 0)
HANDLER_NAMES = [
'StartElementHandler', 'EndElementHandler',
'CharacterDataHandler', 'ProcessingInstructionHandler',
'UnparsedEntityDeclHandler', 'NotationDeclHandler',
'StartNamespaceDeclHandler', 'EndNamespaceDeclHandler',
'CommentHandler', 'StartCdataSectionHandler',
'EndCdataSectionHandler',
'DefaultHandler', 'DefaultHandlerExpand',
#'NotStandaloneHandler',
'ExternalEntityRefHandler'
]
for name in HANDLER_NAMES:
setattr(parser, name, getattr(out, name))
data = '''\ data = '''\
<?xml version="1.0" encoding="iso-8859-1" standalone="no"?> <?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
...@@ -126,108 +58,228 @@ data = '''\ ...@@ -126,108 +58,228 @@ data = '''\
</root> </root>
''' '''
# Produce UTF-8 output # Produce UTF-8 output
parser.returns_unicode = 0 class ParseTest(unittest.TestCase):
try: class Outputter:
parser.Parse(data, 1) def __init__(self):
except expat.error: self.out = []
print '** Error', parser.ErrorCode, expat.ErrorString(parser.ErrorCode)
print '** Line', parser.ErrorLineNumber def StartElementHandler(self, name, attrs):
print '** Column', parser.ErrorColumnNumber self.out.append('Start element: ' + repr(name) + ' ' +
print '** Byte', parser.ErrorByteIndex sortdict(attrs))
# Try the parse again, this time producing Unicode output def EndElementHandler(self, name):
parser = expat.ParserCreate(namespace_separator='!') self.out.append('End element: ' + repr(name))
parser.returns_unicode = 1
def CharacterDataHandler(self, data):
for name in HANDLER_NAMES: data = data.strip()
setattr(parser, name, getattr(out, name)) if data:
try: self.out.append('Character data: ' + repr(data))
parser.Parse(data, 1)
except expat.error: def ProcessingInstructionHandler(self, target, data):
print '** Error', parser.ErrorCode, expat.ErrorString(parser.ErrorCode) self.out.append('PI: ' + repr(target) + ' ' + repr(data))
print '** Line', parser.ErrorLineNumber
print '** Column', parser.ErrorColumnNumber def StartNamespaceDeclHandler(self, prefix, uri):
print '** Byte', parser.ErrorByteIndex self.out.append('NS decl: ' + repr(prefix) + ' ' + repr(uri))
# Try parsing a file def EndNamespaceDeclHandler(self, prefix):
parser = expat.ParserCreate(namespace_separator='!') self.out.append('End of NS decl: ' + repr(prefix))
parser.returns_unicode = 1
def StartCdataSectionHandler(self):
for name in HANDLER_NAMES: self.out.append('Start of CDATA section')
setattr(parser, name, getattr(out, name))
import StringIO def EndCdataSectionHandler(self):
file = StringIO.StringIO(data) self.out.append('End of CDATA section')
try:
parser.ParseFile(file) def CommentHandler(self, text):
except expat.error: self.out.append('Comment: ' + repr(text))
print '** Error', parser.ErrorCode, expat.ErrorString(parser.ErrorCode)
print '** Line', parser.ErrorLineNumber def NotationDeclHandler(self, *args):
print '** Column', parser.ErrorColumnNumber name, base, sysid, pubid = args
print '** Byte', parser.ErrorByteIndex self.out.append('Notation declared: %s' %(args,))
def UnparsedEntityDeclHandler(self, *args):
# Tests that make sure we get errors when the namespace_separator value entityName, base, systemId, publicId, notationName = args
# is illegal, and that we don't for good values: self.out.append('Unparsed entity decl: %s' %(args,))
print
print "Testing constructor for proper handling of namespace_separator values:" def NotStandaloneHandler(self, userData):
expat.ParserCreate() self.out.append('Not standalone')
expat.ParserCreate(namespace_separator=None) return 1
expat.ParserCreate(namespace_separator=' ')
print "Legal values tested o.k." def ExternalEntityRefHandler(self, *args):
try: context, base, sysId, pubId = args
expat.ParserCreate(namespace_separator=42) self.out.append('External entity ref: %s' %(args[1:],))
except TypeError, e: return 1
print "Caught expected TypeError:"
print e def DefaultHandler(self, userData):
else: pass
print "Failed to catch expected TypeError."
def DefaultHandlerExpand(self, userData):
try: pass
expat.ParserCreate(namespace_separator='too long')
except ValueError, e: handler_names = [
print "Caught expected ValueError:" 'StartElementHandler', 'EndElementHandler',
print e 'CharacterDataHandler', 'ProcessingInstructionHandler',
else: 'UnparsedEntityDeclHandler', 'NotationDeclHandler',
print "Failed to catch expected ValueError." 'StartNamespaceDeclHandler', 'EndNamespaceDeclHandler',
'CommentHandler', 'StartCdataSectionHandler',
# ParserCreate() needs to accept a namespace_separator of zero length 'EndCdataSectionHandler',
# to satisfy the requirements of RDF applications that are required 'DefaultHandler', 'DefaultHandlerExpand',
# to simply glue together the namespace URI and the localname. Though #'NotStandaloneHandler',
# considered a wart of the RDF specifications, it needs to be supported. 'ExternalEntityRefHandler'
# ]
# See XML-SIG mailing list thread starting with
# http://mail.python.org/pipermail/xml-sig/2001-April/005202.html def test_utf8(self):
#
expat.ParserCreate(namespace_separator='') # too short out = self.Outputter()
parser = expat.ParserCreate(namespace_separator='!')
# Test the interning machinery. for name in self.handler_names:
p = expat.ParserCreate() setattr(parser, name, getattr(out, name))
L = [] parser.returns_unicode = 0
def collector(name, *args): parser.Parse(data, 1)
L.append(name)
p.StartElementHandler = collector # Verify output
p.EndElementHandler = collector op = out.out
p.Parse("<e> <e/> <e></e> </e>", 1) self.assertEquals(op[0], 'PI: \'xml-stylesheet\' \'href="stylesheet.css"\'')
tag = L[0] self.assertEquals(op[1], "Comment: ' comment data '")
if len(L) != 6: self.assertEquals(op[2], "Notation declared: ('notation', None, 'notation.jpeg', None)")
print "L should only contain 6 entries; found", len(L) self.assertEquals(op[3], "Unparsed entity decl: ('unparsed_entity', None, 'entity.file', None, 'notation')")
for entry in L: self.assertEquals(op[4], "Start element: 'root' {'attr1': 'value1', 'attr2': 'value2\\xe1\\xbd\\x80'}")
if tag is not entry: self.assertEquals(op[5], "NS decl: 'myns' 'http://www.python.org/namespace'")
print "expected L to contain many references to the same string", self.assertEquals(op[6], "Start element: 'http://www.python.org/namespace!subelement' {}")
print "(it didn't)" self.assertEquals(op[7], "Character data: 'Contents of subelements'")
print "L =", repr(L) self.assertEquals(op[8], "End element: 'http://www.python.org/namespace!subelement'")
break self.assertEquals(op[9], "End of NS decl: 'myns'")
self.assertEquals(op[10], "Start element: 'sub2' {}")
# Tests of the buffer_text attribute. self.assertEquals(op[11], 'Start of CDATA section')
import sys self.assertEquals(op[12], "Character data: 'contents of CDATA section'")
self.assertEquals(op[13], 'End of CDATA section')
class TextCollector: self.assertEquals(op[14], "End element: 'sub2'")
def __init__(self, parser): self.assertEquals(op[15], "External entity ref: (None, 'entity.file', None)")
self.assertEquals(op[16], "End element: 'root'")
def test_unicode(self):
# Try the parse again, this time producing Unicode output
out = self.Outputter()
parser = expat.ParserCreate(namespace_separator='!')
parser.returns_unicode = 1
for name in self.handler_names:
setattr(parser, name, getattr(out, name))
parser.Parse(data, 1)
op = out.out
self.assertEquals(op[0], 'PI: u\'xml-stylesheet\' u\'href="stylesheet.css"\'')
self.assertEquals(op[1], "Comment: u' comment data '")
self.assertEquals(op[2], "Notation declared: (u'notation', None, u'notation.jpeg', None)")
self.assertEquals(op[3], "Unparsed entity decl: (u'unparsed_entity', None, u'entity.file', None, u'notation')")
self.assertEquals(op[4], "Start element: u'root' {u'attr1': u'value1', u'attr2': u'value2\\u1f40'}")
self.assertEquals(op[5], "NS decl: u'myns' u'http://www.python.org/namespace'")
self.assertEquals(op[6], "Start element: u'http://www.python.org/namespace!subelement' {}")
self.assertEquals(op[7], "Character data: u'Contents of subelements'")
self.assertEquals(op[8], "End element: u'http://www.python.org/namespace!subelement'")
self.assertEquals(op[9], "End of NS decl: u'myns'")
self.assertEquals(op[10], "Start element: u'sub2' {}")
self.assertEquals(op[11], 'Start of CDATA section')
self.assertEquals(op[12], "Character data: u'contents of CDATA section'")
self.assertEquals(op[13], 'End of CDATA section')
self.assertEquals(op[14], "End element: u'sub2'")
self.assertEquals(op[15], "External entity ref: (None, u'entity.file', None)")
self.assertEquals(op[16], "End element: u'root'")
def test_parse_file(self):
# Try parsing a file
out = self.Outputter()
parser = expat.ParserCreate(namespace_separator='!')
parser.returns_unicode = 1
for name in self.handler_names:
setattr(parser, name, getattr(out, name))
file = StringIO.StringIO(data)
parser.ParseFile(file)
op = out.out
self.assertEquals(op[0], 'PI: u\'xml-stylesheet\' u\'href="stylesheet.css"\'')
self.assertEquals(op[1], "Comment: u' comment data '")
self.assertEquals(op[2], "Notation declared: (u'notation', None, u'notation.jpeg', None)")
self.assertEquals(op[3], "Unparsed entity decl: (u'unparsed_entity', None, u'entity.file', None, u'notation')")
self.assertEquals(op[4], "Start element: u'root' {u'attr1': u'value1', u'attr2': u'value2\\u1f40'}")
self.assertEquals(op[5], "NS decl: u'myns' u'http://www.python.org/namespace'")
self.assertEquals(op[6], "Start element: u'http://www.python.org/namespace!subelement' {}")
self.assertEquals(op[7], "Character data: u'Contents of subelements'")
self.assertEquals(op[8], "End element: u'http://www.python.org/namespace!subelement'")
self.assertEquals(op[9], "End of NS decl: u'myns'")
self.assertEquals(op[10], "Start element: u'sub2' {}")
self.assertEquals(op[11], 'Start of CDATA section')
self.assertEquals(op[12], "Character data: u'contents of CDATA section'")
self.assertEquals(op[13], 'End of CDATA section')
self.assertEquals(op[14], "End element: u'sub2'")
self.assertEquals(op[15], "External entity ref: (None, u'entity.file', None)")
self.assertEquals(op[16], "End element: u'root'")
class NamespaceSeparatorTest(unittest.TestCase):
def test_legal(self):
# Tests that make sure we get errors when the namespace_separator value
# is illegal, and that we don't for good values:
expat.ParserCreate()
expat.ParserCreate(namespace_separator=None)
expat.ParserCreate(namespace_separator=' ')
def test_illegal(self):
try:
expat.ParserCreate(namespace_separator=42)
self.fail()
except TypeError, e:
self.assertEquals(str(e),
'ParserCreate() argument 2 must be string or None, not int')
try:
expat.ParserCreate(namespace_separator='too long')
self.fail()
except ValueError, e:
self.assertEquals(str(e),
'namespace_separator must be at most one character, omitted, or None')
def test_zero_length(self):
# ParserCreate() needs to accept a namespace_separator of zero length
# to satisfy the requirements of RDF applications that are required
# to simply glue together the namespace URI and the localname. Though
# considered a wart of the RDF specifications, it needs to be supported.
#
# See XML-SIG mailing list thread starting with
# http://mail.python.org/pipermail/xml-sig/2001-April/005202.html
#
expat.ParserCreate(namespace_separator='') # too short
class InterningTest(unittest.TestCase):
def test(self):
# Test the interning machinery.
p = expat.ParserCreate()
L = []
def collector(name, *args):
L.append(name)
p.StartElementHandler = collector
p.EndElementHandler = collector
p.Parse("<e> <e/> <e></e> </e>", 1)
tag = L[0]
self.assertEquals(len(L), 6)
for entry in L:
# L should have the same string repeated over and over.
self.assertTrue(tag is entry)
class BufferTextTest(unittest.TestCase):
def setUp(self):
self.stuff = [] self.stuff = []
self.parser = expat.ParserCreate()
self.parser.buffer_text = 1
self.parser.CharacterDataHandler = self.CharacterDataHandler
def check(self, expected, label): def check(self, expected, label):
require(self.stuff == expected, self.assertEquals(self.stuff, expected,
"%s\nstuff = %r\nexpected = %r" "%s\nstuff = %r\nexpected = %r"
% (label, self.stuff, map(unicode, expected))) % (label, self.stuff, map(unicode, expected)))
...@@ -238,9 +290,9 @@ class TextCollector: ...@@ -238,9 +290,9 @@ class TextCollector:
self.stuff.append("<%s>" % name) self.stuff.append("<%s>" % name)
bt = attrs.get("buffer-text") bt = attrs.get("buffer-text")
if bt == "yes": if bt == "yes":
parser.buffer_text = 1 self.parser.buffer_text = 1
elif bt == "no": elif bt == "no":
parser.buffer_text = 0 self.parser.buffer_text = 0
def EndElementHandler(self, name): def EndElementHandler(self, name):
self.stuff.append("</%s>" % name) self.stuff.append("</%s>" % name)
...@@ -248,95 +300,91 @@ class TextCollector: ...@@ -248,95 +300,91 @@ class TextCollector:
def CommentHandler(self, data): def CommentHandler(self, data):
self.stuff.append("<!--%s-->" % data) self.stuff.append("<!--%s-->" % data)
def require(cond, label): def setHandlers(self, handlers=[]):
# similar to confirm(), but no extraneous output for name in handlers:
if not cond: setattr(self.parser, name, getattr(self, name))
raise TestFailed(label)
def test_default_to_disabled(self):
def setup(handlers=[]): parser = expat.ParserCreate()
parser = expat.ParserCreate() self.assertFalse(parser.buffer_text)
require(not parser.buffer_text,
"buffer_text not disabled by default") def test_buffering_enabled(self):
parser.buffer_text = 1 # Make sure buffering is turned on
handler = TextCollector(parser) self.assertTrue(self.parser.buffer_text)
parser.CharacterDataHandler = handler.CharacterDataHandler self.parser.Parse("<a>1<b/>2<c/>3</a>", 1)
for name in handlers: self.assertEquals(self.stuff, ['123'],
setattr(parser, name, getattr(handler, name)) "buffered text not properly collapsed")
return parser, handler
def test1(self):
parser, handler = setup() # XXX This test exposes more detail of Expat's text chunking than we
require(parser.buffer_text, # XXX like, but it tests what we need to concisely.
"text buffering either not acknowledged or not enabled") self.setHandlers(["StartElementHandler"])
parser.Parse("<a>1<b/>2<c/>3</a>", 1) self.parser.Parse("<a>1<b buffer-text='no'/>2\n3<c buffer-text='yes'/>4\n5</a>", 1)
handler.check(["123"], self.assertEquals(self.stuff,
"buffered text not properly collapsed") ["<a>", "1", "<b>", "2", "\n", "3", "<c>", "4\n5"],
"buffering control not reacting as expected")
# XXX This test exposes more detail of Expat's text chunking than we
# XXX like, but it tests what we need to concisely. def test2(self):
parser, handler = setup(["StartElementHandler"]) self.parser.Parse("<a>1<b/>&lt;2&gt;<c/>&#32;\n&#x20;3</a>", 1)
parser.Parse("<a>1<b buffer-text='no'/>2\n3<c buffer-text='yes'/>4\n5</a>", 1) self.assertEquals(self.stuff, ["1<2> \n 3"],
handler.check(["<a>", "1", "<b>", "2", "\n", "3", "<c>", "4\n5"], "buffered text not properly collapsed")
"buffering control not reacting as expected")
def test3(self):
parser, handler = setup() self.setHandlers(["StartElementHandler"])
parser.Parse("<a>1<b/>&lt;2&gt;<c/>&#32;\n&#x20;3</a>", 1) self.parser.Parse("<a>1<b/>2<c/>3</a>", 1)
handler.check(["1<2> \n 3"], self.assertEquals(self.stuff, ["<a>", "1", "<b>", "2", "<c>", "3"],
"buffered text not properly collapsed") "buffered text not properly split")
parser, handler = setup(["StartElementHandler"]) def test4(self):
parser.Parse("<a>1<b/>2<c/>3</a>", 1) self.setHandlers(["StartElementHandler", "EndElementHandler"])
handler.check(["<a>", "1", "<b>", "2", "<c>", "3"], self.parser.CharacterDataHandler = None
"buffered text not properly split") self.parser.Parse("<a>1<b/>2<c/>3</a>", 1)
self.assertEquals(self.stuff,
parser, handler = setup(["StartElementHandler", "EndElementHandler"]) ["<a>", "<b>", "</b>", "<c>", "</c>", "</a>"])
parser.CharacterDataHandler = None
parser.Parse("<a>1<b/>2<c/>3</a>", 1) def test5(self):
handler.check(["<a>", "<b>", "</b>", "<c>", "</c>", "</a>"], self.setHandlers(["StartElementHandler", "EndElementHandler"])
"huh?") self.parser.Parse("<a>1<b></b>2<c/>3</a>", 1)
self.assertEquals(self.stuff,
parser, handler = setup(["StartElementHandler", "EndElementHandler"]) ["<a>", "1", "<b>", "</b>", "2", "<c>", "</c>", "3", "</a>"])
parser.Parse("<a>1<b></b>2<c/>3</a>", 1)
handler.check(["<a>", "1", "<b>", "</b>", "2", "<c>", "</c>", "3", "</a>"], def test6(self):
"huh?") self.setHandlers(["CommentHandler", "EndElementHandler",
"StartElementHandler"])
parser, handler = setup(["CommentHandler", "EndElementHandler", self.parser.Parse("<a>1<b/>2<c></c>345</a> ", 1)
"StartElementHandler"]) self.assertEquals(self.stuff,
parser.Parse("<a>1<b/>2<c></c>345</a> ", 1) ["<a>", "1", "<b>", "</b>", "2", "<c>", "</c>", "345", "</a>"],
handler.check(["<a>", "1", "<b>", "</b>", "2", "<c>", "</c>", "345", "</a>"], "buffered text not properly split")
"buffered text not properly split")
def test7(self):
parser, handler = setup(["CommentHandler", "EndElementHandler", self.setHandlers(["CommentHandler", "EndElementHandler",
"StartElementHandler"]) "StartElementHandler"])
parser.Parse("<a>1<b/>2<c></c>3<!--abc-->4<!--def-->5</a> ", 1) self.parser.Parse("<a>1<b/>2<c></c>3<!--abc-->4<!--def-->5</a> ", 1)
handler.check(["<a>", "1", "<b>", "</b>", "2", "<c>", "</c>", "3", self.assertEquals(self.stuff,
"<!--abc-->", "4", "<!--def-->", "5", "</a>"], ["<a>", "1", "<b>", "</b>", "2", "<c>", "</c>", "3",
"buffered text not properly split") "<!--abc-->", "4", "<!--def-->", "5", "</a>"],
"buffered text not properly split")
# Test handling of exception from callback: # Test handling of exception from callback:
def StartElementHandler(name, attrs): class HandlerExceptionTest(unittest.TestCase):
raise RuntimeError(name) def StartElementHandler(self, name, attrs):
raise RuntimeError(name)
parser = expat.ParserCreate() def test(self):
parser.StartElementHandler = StartElementHandler parser = expat.ParserCreate()
parser.StartElementHandler = self.StartElementHandler
try:
parser.Parse("<a><b><c/></b></a>", 1)
self.fail()
except RuntimeError, e:
self.assertEquals(e.args[0], 'a',
"Expected RuntimeError for element 'a', but" + \
" found %r" % e.args[0])
try:
parser.Parse("<a><b><c/></b></a>", 1)
except RuntimeError, e:
if e.args[0] != "a":
print "Expected RuntimeError for element 'a'; found %r" % e.args[0]
else:
print "Expected RuntimeError for 'a'"
# Test Current* members: # Test Current* members:
class PositionTest: class PositionTest(unittest.TestCase):
def __init__(self, expected_list, parser):
self.parser = parser
self.parser.StartElementHandler = self.StartElementHandler
self.parser.EndElementHandler = self.EndElementHandler
self.expected_list = expected_list
self.upto = 0
def StartElementHandler(self, name, attrs): def StartElementHandler(self, name, attrs):
self.check_pos('s') self.check_pos('s')
...@@ -348,41 +396,54 @@ class PositionTest: ...@@ -348,41 +396,54 @@ class PositionTest:
self.parser.CurrentByteIndex, self.parser.CurrentByteIndex,
self.parser.CurrentLineNumber, self.parser.CurrentLineNumber,
self.parser.CurrentColumnNumber) self.parser.CurrentColumnNumber)
require(self.upto < len(self.expected_list), self.assertTrue(self.upto < len(self.expected_list),
'too many parser events') 'too many parser events')
expected = self.expected_list[self.upto] expected = self.expected_list[self.upto]
require(pos == expected, self.assertEquals(pos, expected,
'expected position %s, got %s' % (expected, pos)) 'Expected position %s, got position %s' %(pos, expected))
self.upto += 1 self.upto += 1
def test(self):
parser = expat.ParserCreate() self.parser = expat.ParserCreate()
handler = PositionTest([('s', 0, 1, 0), ('s', 5, 2, 1), ('s', 11, 3, 2), self.parser.StartElementHandler = self.StartElementHandler
('e', 15, 3, 6), ('e', 17, 4, 1), ('e', 22, 5, 0)], self.parser.EndElementHandler = self.EndElementHandler
parser) self.upto = 0
parser.Parse('''<a> self.expected_list = [('s', 0, 1, 0), ('s', 5, 2, 1), ('s', 11, 3, 2),
<b> ('e', 15, 3, 6), ('e', 17, 4, 1), ('e', 22, 5, 0)]
<c/>
</b> xml = '<a>\n <b>\n <c/>\n </b>\n</a>'
</a>''', 1) self.parser.Parse(xml, 1)
def test_parse_only_xml_data(): class sf1296433Test(unittest.TestCase):
# http://python.org/sf/1296433 def test_parse_only_xml_data(self):
# # http://python.org/sf/1296433
xml = "<?xml version='1.0' encoding='iso8859'?><s>%s</s>" % ('a' * 1025) #
# this one doesn't crash xml = "<?xml version='1.0' encoding='iso8859'?><s>%s</s>" % ('a' * 1025)
#xml = "<?xml version='1.0'?><s>%s</s>" % ('a' * 10000) # this one doesn't crash
#xml = "<?xml version='1.0'?><s>%s</s>" % ('a' * 10000)
def handler(text):
raise Exception class SpecificException(Exception):
pass
parser = expat.ParserCreate()
parser.CharacterDataHandler = handler def handler(text):
raise SpecificException
try:
parser.Parse(xml) parser = expat.ParserCreate()
except: parser.CharacterDataHandler = handler
pass
self.assertRaises(Exception, parser.Parse, xml)
test_parse_only_xml_data()
def test_main():
run_unittest(SetAttributeTest,
ParseTest,
NamespaceSeparatorTest,
InterningTest,
BufferTextTest,
HandlerExceptionTest,
PositionTest,
sf1296433Test)
if __name__ == "__main__":
test_main()
...@@ -13,26 +13,66 @@ from xml.sax.saxutils import XMLGenerator, escape, unescape, quoteattr, \ ...@@ -13,26 +13,66 @@ from xml.sax.saxutils import XMLGenerator, escape, unescape, quoteattr, \
from xml.sax.expatreader import create_parser from xml.sax.expatreader import create_parser
from xml.sax.xmlreader import InputSource, AttributesImpl, AttributesNSImpl from xml.sax.xmlreader import InputSource, AttributesImpl, AttributesNSImpl
from cStringIO import StringIO from cStringIO import StringIO
from test.test_support import verify, verbose, TestFailed, findfile from test.test_support import findfile, run_unittest
import unittest
import os import os
# ===== Utilities ns_uri = "http://www.python.org/xml-ns/saxtest/"
tests = 0
failures = []
def confirm(outcome, name):
global tests
tests = tests + 1
if outcome:
if verbose:
print "Passed", name
else:
failures.append(name)
def test_make_parser2(): class XmlTestBase(unittest.TestCase):
try: def verify_empty_attrs(self, attrs):
self.assertRaises(KeyError, attrs.getValue, "attr")
self.assertRaises(KeyError, attrs.getValueByQName, "attr")
self.assertRaises(KeyError, attrs.getNameByQName, "attr")
self.assertRaises(KeyError, attrs.getQNameByName, "attr")
self.assertRaises(KeyError, attrs.__getitem__, "attr")
self.assertEquals(attrs.getLength(), 0)
self.assertEquals(attrs.getNames(), [])
self.assertEquals(attrs.getQNames(), [])
self.assertEquals(len(attrs), 0)
self.assertFalse(attrs.has_key("attr"))
self.assertEquals(attrs.keys(), [])
self.assertEquals(attrs.get("attrs"), None)
self.assertEquals(attrs.get("attrs", 25), 25)
self.assertEquals(attrs.items(), [])
self.assertEquals(attrs.values(), [])
def verify_empty_nsattrs(self, attrs):
self.assertRaises(KeyError, attrs.getValue, (ns_uri, "attr"))
self.assertRaises(KeyError, attrs.getValueByQName, "ns:attr")
self.assertRaises(KeyError, attrs.getNameByQName, "ns:attr")
self.assertRaises(KeyError, attrs.getQNameByName, (ns_uri, "attr"))
self.assertRaises(KeyError, attrs.__getitem__, (ns_uri, "attr"))
self.assertEquals(attrs.getLength(), 0)
self.assertEquals(attrs.getNames(), [])
self.assertEquals(attrs.getQNames(), [])
self.assertEquals(len(attrs), 0)
self.assertFalse(attrs.has_key((ns_uri, "attr")))
self.assertEquals(attrs.keys(), [])
self.assertEquals(attrs.get((ns_uri, "attr")), None)
self.assertEquals(attrs.get((ns_uri, "attr"), 25), 25)
self.assertEquals(attrs.items(), [])
self.assertEquals(attrs.values(), [])
def verify_attrs_wattr(self, attrs):
self.assertEquals(attrs.getLength(), 1)
self.assertEquals(attrs.getNames(), ["attr"])
self.assertEquals(attrs.getQNames(), ["attr"])
self.assertEquals(len(attrs), 1)
self.assertTrue(attrs.has_key("attr"))
self.assertEquals(attrs.keys(), ["attr"])
self.assertEquals(attrs.get("attr"), "val")
self.assertEquals(attrs.get("attr", 25), "val")
self.assertEquals(attrs.items(), [("attr", "val")])
self.assertEquals(attrs.values(), ["val"])
self.assertEquals(attrs.getValue("attr"), "val")
self.assertEquals(attrs.getValueByQName("attr"), "val")
self.assertEquals(attrs.getNameByQName("attr"), "attr")
self.assertEquals(attrs["attr"], "val")
self.assertEquals(attrs.getQNameByName("attr"), "attr")
class MakeParserTest(unittest.TestCase):
def test_make_parser2(self):
# Creating parsers several times in a row should succeed. # Creating parsers several times in a row should succeed.
# Testing this because there have been failures of this kind # Testing this because there have been failures of this kind
# before. # before.
...@@ -48,10 +88,6 @@ def test_make_parser2(): ...@@ -48,10 +88,6 @@ def test_make_parser2():
p = make_parser() p = make_parser()
from xml.sax import make_parser from xml.sax import make_parser
p = make_parser() p = make_parser()
except:
return 0
else:
return p
# =========================================================================== # ===========================================================================
...@@ -60,215 +96,214 @@ def test_make_parser2(): ...@@ -60,215 +96,214 @@ def test_make_parser2():
# #
# =========================================================================== # ===========================================================================
# ===== escape class SaxutilsTest(unittest.TestCase):
# ===== escape
def test_escape_basic(): def test_escape_basic(self):
return escape("Donald Duck & Co") == "Donald Duck &amp; Co" self.assertEquals(escape("Donald Duck & Co"), "Donald Duck &amp; Co")
def test_escape_all(): def test_escape_all(self):
return escape("<Donald Duck & Co>") == "&lt;Donald Duck &amp; Co&gt;" self.assertEquals(escape("<Donald Duck & Co>"),
"&lt;Donald Duck &amp; Co&gt;")
def test_escape_extra():
return escape("Hei p deg", {"" : "&aring;"}) == "Hei p&aring; deg" def test_escape_extra(self):
self.assertEquals(escape("Hei p deg", {"" : "&aring;"}),
# ===== unescape "Hei p&aring; deg")
def test_unescape_basic(): # ===== unescape
return unescape("Donald Duck &amp; Co") == "Donald Duck & Co" def test_unescape_basic(self):
self.assertEquals(unescape("Donald Duck &amp; Co"), "Donald Duck & Co")
def test_unescape_all():
return unescape("&lt;Donald Duck &amp; Co&gt;") == "<Donald Duck & Co>" def test_unescape_all(self):
self.assertEquals(unescape("&lt;Donald Duck &amp; Co&gt;"),
def test_unescape_extra(): "<Donald Duck & Co>")
return unescape("Hei p deg", {"" : "&aring;"}) == "Hei p&aring; deg"
def test_unescape_extra(self):
def test_unescape_amp_extra(): self.assertEquals(unescape("Hei p deg", {"" : "&aring;"}),
return unescape("&amp;foo;", {"&foo;": "splat"}) == "&foo;" "Hei p&aring; deg")
# ===== quoteattr def test_unescape_amp_extra(self):
self.assertEquals(unescape("&amp;foo;", {"&foo;": "splat"}), "&foo;")
def test_quoteattr_basic():
return quoteattr("Donald Duck & Co") == '"Donald Duck &amp; Co"' # ===== quoteattr
def test_quoteattr_basic(self):
def test_single_quoteattr(): self.assertEquals(quoteattr("Donald Duck & Co"),
return (quoteattr('Includes "double" quotes') '"Donald Duck &amp; Co"')
== '\'Includes "double" quotes\'')
def test_single_quoteattr(self):
def test_double_quoteattr(): self.assertEquals(quoteattr('Includes "double" quotes'),
return (quoteattr("Includes 'single' quotes") '\'Includes "double" quotes\'')
== "\"Includes 'single' quotes\"")
def test_double_quoteattr(self):
def test_single_double_quoteattr(): self.assertEquals(quoteattr("Includes 'single' quotes"),
return (quoteattr("Includes 'single' and \"double\" quotes") "\"Includes 'single' quotes\"")
== "\"Includes 'single' and &quot;double&quot; quotes\"")
def test_single_double_quoteattr(self):
# ===== make_parser self.assertEquals(quoteattr("Includes 'single' and \"double\" quotes"),
"\"Includes 'single' and &quot;double&quot; quotes\"")
def test_make_parser():
try: # ===== make_parser
def test_make_parser(self):
# Creating a parser should succeed - it should fall back # Creating a parser should succeed - it should fall back
# to the expatreader # to the expatreader
p = make_parser(['xml.parsers.no_such_parser']) p = make_parser(['xml.parsers.no_such_parser'])
except:
return 0
else:
return p
# ===== XMLGenerator # ===== XMLGenerator
start = '<?xml version="1.0" encoding="iso-8859-1"?>\n' start = '<?xml version="1.0" encoding="iso-8859-1"?>\n'
def test_xmlgen_basic(): class XmlgenTest(unittest.TestCase):
result = StringIO() def test_xmlgen_basic(self):
gen = XMLGenerator(result) result = StringIO()
gen.startDocument() gen = XMLGenerator(result)
gen.startElement("doc", {}) gen.startDocument()
gen.endElement("doc") gen.startElement("doc", {})
gen.endDocument() gen.endElement("doc")
gen.endDocument()
return result.getvalue() == start + "<doc></doc>"
self.assertEquals(result.getvalue(), start + "<doc></doc>")
def test_xmlgen_content():
result = StringIO() def test_xmlgen_content(self):
gen = XMLGenerator(result) result = StringIO()
gen = XMLGenerator(result)
gen.startDocument()
gen.startElement("doc", {}) gen.startDocument()
gen.characters("huhei") gen.startElement("doc", {})
gen.endElement("doc") gen.characters("huhei")
gen.endDocument() gen.endElement("doc")
gen.endDocument()
return result.getvalue() == start + "<doc>huhei</doc>"
self.assertEquals(result.getvalue(), start + "<doc>huhei</doc>")
def test_xmlgen_pi():
result = StringIO() def test_xmlgen_pi(self):
gen = XMLGenerator(result) result = StringIO()
gen = XMLGenerator(result)
gen.startDocument()
gen.processingInstruction("test", "data") gen.startDocument()
gen.startElement("doc", {}) gen.processingInstruction("test", "data")
gen.endElement("doc") gen.startElement("doc", {})
gen.endDocument() gen.endElement("doc")
gen.endDocument()
return result.getvalue() == start + "<?test data?><doc></doc>"
self.assertEquals(result.getvalue(), start + "<?test data?><doc></doc>")
def test_xmlgen_content_escape():
result = StringIO() def test_xmlgen_content_escape(self):
gen = XMLGenerator(result) result = StringIO()
gen = XMLGenerator(result)
gen.startDocument()
gen.startElement("doc", {}) gen.startDocument()
gen.characters("<huhei&") gen.startElement("doc", {})
gen.endElement("doc") gen.characters("<huhei&")
gen.endDocument() gen.endElement("doc")
gen.endDocument()
return result.getvalue() == start + "<doc>&lt;huhei&amp;</doc>"
self.assertEquals(result.getvalue(),
def test_xmlgen_attr_escape(): start + "<doc>&lt;huhei&amp;</doc>")
result = StringIO()
gen = XMLGenerator(result) def test_xmlgen_attr_escape(self):
result = StringIO()
gen.startDocument() gen = XMLGenerator(result)
gen.startElement("doc", {"a": '"'})
gen.startElement("e", {"a": "'"}) gen.startDocument()
gen.endElement("e") gen.startElement("doc", {"a": '"'})
gen.startElement("e", {"a": "'\""}) gen.startElement("e", {"a": "'"})
gen.endElement("e") gen.endElement("e")
gen.startElement("e", {"a": "\n\r\t"}) gen.startElement("e", {"a": "'\""})
gen.endElement("e") gen.endElement("e")
gen.endElement("doc") gen.startElement("e", {"a": "\n\r\t"})
gen.endDocument() gen.endElement("e")
gen.endElement("doc")
return result.getvalue() == start + ("<doc a='\"'><e a=\"'\"></e>" gen.endDocument()
"<e a=\"'&quot;\"></e>"
"<e a=\"&#10;&#13;&#9;\"></e></doc>") self.assertEquals(result.getvalue(), start +
("<doc a='\"'><e a=\"'\"></e>"
def test_xmlgen_ignorable(): "<e a=\"'&quot;\"></e>"
result = StringIO() "<e a=\"&#10;&#13;&#9;\"></e></doc>"))
gen = XMLGenerator(result)
def test_xmlgen_ignorable(self):
gen.startDocument() result = StringIO()
gen.startElement("doc", {}) gen = XMLGenerator(result)
gen.ignorableWhitespace(" ")
gen.endElement("doc") gen.startDocument()
gen.endDocument() gen.startElement("doc", {})
gen.ignorableWhitespace(" ")
return result.getvalue() == start + "<doc> </doc>" gen.endElement("doc")
gen.endDocument()
ns_uri = "http://www.python.org/xml-ns/saxtest/"
self.assertEquals(result.getvalue(), start + "<doc> </doc>")
def test_xmlgen_ns():
result = StringIO() def test_xmlgen_ns(self):
gen = XMLGenerator(result) result = StringIO()
gen = XMLGenerator(result)
gen.startDocument()
gen.startPrefixMapping("ns1", ns_uri) gen.startDocument()
gen.startElementNS((ns_uri, "doc"), "ns1:doc", {}) gen.startPrefixMapping("ns1", ns_uri)
# add an unqualified name gen.startElementNS((ns_uri, "doc"), "ns1:doc", {})
gen.startElementNS((None, "udoc"), None, {}) # add an unqualified name
gen.endElementNS((None, "udoc"), None) gen.startElementNS((None, "udoc"), None, {})
gen.endElementNS((ns_uri, "doc"), "ns1:doc") gen.endElementNS((None, "udoc"), None)
gen.endPrefixMapping("ns1") gen.endElementNS((ns_uri, "doc"), "ns1:doc")
gen.endDocument() gen.endPrefixMapping("ns1")
gen.endDocument()
return result.getvalue() == start + \
self.assertEquals(result.getvalue(), start + \
('<ns1:doc xmlns:ns1="%s"><udoc></udoc></ns1:doc>' % ('<ns1:doc xmlns:ns1="%s"><udoc></udoc></ns1:doc>' %
ns_uri) ns_uri))
def test_1463026_1(): def test_1463026_1(self):
result = StringIO() result = StringIO()
gen = XMLGenerator(result) gen = XMLGenerator(result)
gen.startDocument() gen.startDocument()
gen.startElementNS((None, 'a'), 'a', {(None, 'b'):'c'}) gen.startElementNS((None, 'a'), 'a', {(None, 'b'):'c'})
gen.endElementNS((None, 'a'), 'a') gen.endElementNS((None, 'a'), 'a')
gen.endDocument() gen.endDocument()
return result.getvalue() == start+'<a b="c"></a>' self.assertEquals(result.getvalue(), start+'<a b="c"></a>')
def test_1463026_2(): def test_1463026_2(self):
result = StringIO() result = StringIO()
gen = XMLGenerator(result) gen = XMLGenerator(result)
gen.startDocument() gen.startDocument()
gen.startPrefixMapping(None, 'qux') gen.startPrefixMapping(None, 'qux')
gen.startElementNS(('qux', 'a'), 'a', {}) gen.startElementNS(('qux', 'a'), 'a', {})
gen.endElementNS(('qux', 'a'), 'a') gen.endElementNS(('qux', 'a'), 'a')
gen.endPrefixMapping(None) gen.endPrefixMapping(None)
gen.endDocument() gen.endDocument()
return result.getvalue() == start+'<a xmlns="qux"></a>' self.assertEquals(result.getvalue(), start+'<a xmlns="qux"></a>')
def test_1463026_3(): def test_1463026_3(self):
result = StringIO() result = StringIO()
gen = XMLGenerator(result) gen = XMLGenerator(result)
gen.startDocument() gen.startDocument()
gen.startPrefixMapping('my', 'qux') gen.startPrefixMapping('my', 'qux')
gen.startElementNS(('qux', 'a'), 'a', {(None, 'b'):'c'}) gen.startElementNS(('qux', 'a'), 'a', {(None, 'b'):'c'})
gen.endElementNS(('qux', 'a'), 'a') gen.endElementNS(('qux', 'a'), 'a')
gen.endPrefixMapping('my') gen.endPrefixMapping('my')
gen.endDocument() gen.endDocument()
return result.getvalue() == start+'<my:a xmlns:my="qux" b="c"></my:a>' self.assertEquals(result.getvalue(),
start+'<my:a xmlns:my="qux" b="c"></my:a>')
# ===== Xmlfilterbase
def test_filter_basic(): class XMLFilterBaseTest(unittest.TestCase):
result = StringIO() def test_filter_basic(self):
gen = XMLGenerator(result) result = StringIO()
filter = XMLFilterBase() gen = XMLGenerator(result)
filter.setContentHandler(gen) filter = XMLFilterBase()
filter.setContentHandler(gen)
filter.startDocument() filter.startDocument()
filter.startElement("doc", {}) filter.startElement("doc", {})
filter.characters("content") filter.characters("content")
filter.ignorableWhitespace(" ") filter.ignorableWhitespace(" ")
filter.endElement("doc") filter.endElement("doc")
filter.endDocument() filter.endDocument()
return result.getvalue() == start + "<doc>content </doc>" self.assertEquals(result.getvalue(), start + "<doc>content </doc>")
# =========================================================================== # ===========================================================================
# #
...@@ -276,294 +311,294 @@ def test_filter_basic(): ...@@ -276,294 +311,294 @@ def test_filter_basic():
# #
# =========================================================================== # ===========================================================================
# ===== XMLReader support
def test_expat_file():
parser = create_parser()
result = StringIO()
xmlgen = XMLGenerator(result)
parser.setContentHandler(xmlgen)
parser.parse(open(findfile("test"+os.extsep+"xml")))
return result.getvalue() == xml_test_out
# ===== DTDHandler support
class TestDTDHandler:
def __init__(self):
self._notations = []
self._entities = []
def notationDecl(self, name, publicId, systemId):
self._notations.append((name, publicId, systemId))
def unparsedEntityDecl(self, name, publicId, systemId, ndata):
self._entities.append((name, publicId, systemId, ndata))
def test_expat_dtdhandler():
parser = create_parser()
handler = TestDTDHandler()
parser.setDTDHandler(handler)
parser.feed('<!DOCTYPE doc [\n')
parser.feed(' <!ENTITY img SYSTEM "expat.gif" NDATA GIF>\n')
parser.feed(' <!NOTATION GIF PUBLIC "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN">\n')
parser.feed(']>\n')
parser.feed('<doc></doc>')
parser.close()
return handler._notations == [("GIF", "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN", None)] and \
handler._entities == [("img", None, "expat.gif", "GIF")]
# ===== EntityResolver support
class TestEntityResolver:
def resolveEntity(self, publicId, systemId):
inpsrc = InputSource()
inpsrc.setByteStream(StringIO("<entity/>"))
return inpsrc
def test_expat_entityresolver():
parser = create_parser()
parser.setEntityResolver(TestEntityResolver())
result = StringIO()
parser.setContentHandler(XMLGenerator(result))
parser.feed('<!DOCTYPE doc [\n')
parser.feed(' <!ENTITY test SYSTEM "whatever">\n')
parser.feed(']>\n')
parser.feed('<doc>&test;</doc>')
parser.close()
return result.getvalue() == start + "<doc><entity></entity></doc>"
# ===== Attributes support
class AttrGatherer(ContentHandler):
def startElement(self, name, attrs):
self._attrs = attrs
def startElementNS(self, name, qname, attrs):
self._attrs = attrs
def test_expat_attrs_empty():
parser = create_parser()
gather = AttrGatherer()
parser.setContentHandler(gather)
parser.feed("<doc/>")
parser.close()
return verify_empty_attrs(gather._attrs)
def test_expat_attrs_wattr():
parser = create_parser()
gather = AttrGatherer()
parser.setContentHandler(gather)
parser.feed("<doc attr='val'/>")
parser.close()
return verify_attrs_wattr(gather._attrs)
def test_expat_nsattrs_empty():
parser = create_parser(1)
gather = AttrGatherer()
parser.setContentHandler(gather)
parser.feed("<doc/>")
parser.close()
return verify_empty_nsattrs(gather._attrs)
def test_expat_nsattrs_wattr():
parser = create_parser(1)
gather = AttrGatherer()
parser.setContentHandler(gather)
parser.feed("<doc xmlns:ns='%s' ns:attr='val'/>" % ns_uri)
parser.close()
attrs = gather._attrs
return attrs.getLength() == 1 and \
attrs.getNames() == [(ns_uri, "attr")] and \
(attrs.getQNames() == [] or attrs.getQNames() == ["ns:attr"]) and \
len(attrs) == 1 and \
attrs.has_key((ns_uri, "attr")) and \
attrs.keys() == [(ns_uri, "attr")] and \
attrs.get((ns_uri, "attr")) == "val" and \
attrs.get((ns_uri, "attr"), 25) == "val" and \
attrs.items() == [((ns_uri, "attr"), "val")] and \
attrs.values() == ["val"] and \
attrs.getValue((ns_uri, "attr")) == "val" and \
attrs[(ns_uri, "attr")] == "val"
# ===== InputSource support
xml_test_out = open(findfile("test"+os.extsep+"xml"+os.extsep+"out")).read() xml_test_out = open(findfile("test"+os.extsep+"xml"+os.extsep+"out")).read()
def test_expat_inpsource_filename(): class ExpatReaderTest(XmlTestBase):
parser = create_parser()
result = StringIO() # ===== XMLReader support
xmlgen = XMLGenerator(result)
parser.setContentHandler(xmlgen)
parser.parse(findfile("test"+os.extsep+"xml"))
return result.getvalue() == xml_test_out
def test_expat_inpsource_sysid():
parser = create_parser()
result = StringIO()
xmlgen = XMLGenerator(result)
parser.setContentHandler(xmlgen)
parser.parse(InputSource(findfile("test"+os.extsep+"xml")))
return result.getvalue() == xml_test_out
def test_expat_inpsource_stream():
parser = create_parser()
result = StringIO()
xmlgen = XMLGenerator(result)
parser.setContentHandler(xmlgen)
inpsrc = InputSource()
inpsrc.setByteStream(open(findfile("test"+os.extsep+"xml")))
parser.parse(inpsrc)
return result.getvalue() == xml_test_out
# ===== IncrementalParser support
def test_expat_incremental(): def test_expat_file(self):
result = StringIO() parser = create_parser()
xmlgen = XMLGenerator(result) result = StringIO()
parser = create_parser() xmlgen = XMLGenerator(result)
parser.setContentHandler(xmlgen)
parser.feed("<doc>") parser.setContentHandler(xmlgen)
parser.feed("</doc>") parser.parse(open(findfile("test"+os.extsep+"xml")))
parser.close()
return result.getvalue() == start + "<doc></doc>" self.assertEquals(result.getvalue(), xml_test_out)
def test_expat_incremental_reset(): # ===== DTDHandler support
result = StringIO()
xmlgen = XMLGenerator(result)
parser = create_parser()
parser.setContentHandler(xmlgen)
parser.feed("<doc>") class TestDTDHandler:
parser.feed("text")
result = StringIO() def __init__(self):
xmlgen = XMLGenerator(result) self._notations = []
parser.setContentHandler(xmlgen) self._entities = []
parser.reset()
parser.feed("<doc>") def notationDecl(self, name, publicId, systemId):
parser.feed("text") self._notations.append((name, publicId, systemId))
parser.feed("</doc>")
parser.close()
return result.getvalue() == start + "<doc>text</doc>" def unparsedEntityDecl(self, name, publicId, systemId, ndata):
self._entities.append((name, publicId, systemId, ndata))
# ===== Locator support def test_expat_dtdhandler(self):
parser = create_parser()
handler = self.TestDTDHandler()
parser.setDTDHandler(handler)
def test_expat_locator_noinfo(): parser.feed('<!DOCTYPE doc [\n')
result = StringIO() parser.feed(' <!ENTITY img SYSTEM "expat.gif" NDATA GIF>\n')
xmlgen = XMLGenerator(result) parser.feed(' <!NOTATION GIF PUBLIC "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN">\n')
parser = create_parser() parser.feed(']>\n')
parser.setContentHandler(xmlgen) parser.feed('<doc></doc>')
parser.close()
parser.feed("<doc>") self.assertEquals(handler._notations,
parser.feed("</doc>") [("GIF", "-//CompuServe//NOTATION Graphics Interchange Format 89a//EN", None)])
parser.close() self.assertEquals(handler._entities, [("img", None, "expat.gif", "GIF")])
return parser.getSystemId() is None and \ # ===== EntityResolver support
parser.getPublicId() is None and \
parser.getLineNumber() == 1
def test_expat_locator_withinfo(): class TestEntityResolver:
result = StringIO()
xmlgen = XMLGenerator(result)
parser = create_parser()
parser.setContentHandler(xmlgen)
parser.parse(findfile("test.xml"))
return parser.getSystemId() == findfile("test.xml") and \
parser.getPublicId() is None
def resolveEntity(self, publicId, systemId):
inpsrc = InputSource()
inpsrc.setByteStream(StringIO("<entity/>"))
return inpsrc
def test_expat_entityresolver(self):
parser = create_parser()
parser.setEntityResolver(self.TestEntityResolver())
result = StringIO()
parser.setContentHandler(XMLGenerator(result))
parser.feed('<!DOCTYPE doc [\n')
parser.feed(' <!ENTITY test SYSTEM "whatever">\n')
parser.feed(']>\n')
parser.feed('<doc>&test;</doc>')
parser.close()
self.assertEquals(result.getvalue(), start +
"<doc><entity></entity></doc>")
# ===== Attributes support
class AttrGatherer(ContentHandler):
def startElement(self, name, attrs):
self._attrs = attrs
def startElementNS(self, name, qname, attrs):
self._attrs = attrs
def test_expat_attrs_empty(self):
parser = create_parser()
gather = self.AttrGatherer()
parser.setContentHandler(gather)
parser.feed("<doc/>")
parser.close()
self.verify_empty_attrs(gather._attrs)
def test_expat_attrs_wattr(self):
parser = create_parser()
gather = self.AttrGatherer()
parser.setContentHandler(gather)
parser.feed("<doc attr='val'/>")
parser.close()
self.verify_attrs_wattr(gather._attrs)
def test_expat_nsattrs_empty(self):
parser = create_parser(1)
gather = self.AttrGatherer()
parser.setContentHandler(gather)
parser.feed("<doc/>")
parser.close()
self.verify_empty_nsattrs(gather._attrs)
def test_expat_nsattrs_wattr(self):
parser = create_parser(1)
gather = self.AttrGatherer()
parser.setContentHandler(gather)
parser.feed("<doc xmlns:ns='%s' ns:attr='val'/>" % ns_uri)
parser.close()
attrs = gather._attrs
self.assertEquals(attrs.getLength(), 1)
self.assertEquals(attrs.getNames(), [(ns_uri, "attr")])
self.assertTrue((attrs.getQNames() == [] or
attrs.getQNames() == ["ns:attr"]))
self.assertEquals(len(attrs), 1)
self.assertTrue(attrs.has_key((ns_uri, "attr")))
self.assertEquals(attrs.get((ns_uri, "attr")), "val")
self.assertEquals(attrs.get((ns_uri, "attr"), 25), "val")
self.assertEquals(attrs.items(), [((ns_uri, "attr"), "val")])
self.assertEquals(attrs.values(), ["val"])
self.assertEquals(attrs.getValue((ns_uri, "attr")), "val")
self.assertEquals(attrs[(ns_uri, "attr")], "val")
# ===== InputSource support
def test_expat_inpsource_filename(self):
parser = create_parser()
result = StringIO()
xmlgen = XMLGenerator(result)
parser.setContentHandler(xmlgen)
parser.parse(findfile("test"+os.extsep+"xml"))
self.assertEquals(result.getvalue(), xml_test_out)
def test_expat_inpsource_sysid(self):
parser = create_parser()
result = StringIO()
xmlgen = XMLGenerator(result)
parser.setContentHandler(xmlgen)
parser.parse(InputSource(findfile("test"+os.extsep+"xml")))
self.assertEquals(result.getvalue(), xml_test_out)
def test_expat_inpsource_stream(self):
parser = create_parser()
result = StringIO()
xmlgen = XMLGenerator(result)
parser.setContentHandler(xmlgen)
inpsrc = InputSource()
inpsrc.setByteStream(open(findfile("test"+os.extsep+"xml")))
parser.parse(inpsrc)
self.assertEquals(result.getvalue(), xml_test_out)
# ===== IncrementalParser support
def test_expat_incremental(self):
result = StringIO()
xmlgen = XMLGenerator(result)
parser = create_parser()
parser.setContentHandler(xmlgen)
parser.feed("<doc>")
parser.feed("</doc>")
parser.close()
self.assertEquals(result.getvalue(), start + "<doc></doc>")
def test_expat_incremental_reset(self):
result = StringIO()
xmlgen = XMLGenerator(result)
parser = create_parser()
parser.setContentHandler(xmlgen)
parser.feed("<doc>")
parser.feed("text")
result = StringIO()
xmlgen = XMLGenerator(result)
parser.setContentHandler(xmlgen)
parser.reset()
parser.feed("<doc>")
parser.feed("text")
parser.feed("</doc>")
parser.close()
self.assertEquals(result.getvalue(), start + "<doc>text</doc>")
# ===== Locator support
def test_expat_locator_noinfo(self):
result = StringIO()
xmlgen = XMLGenerator(result)
parser = create_parser()
parser.setContentHandler(xmlgen)
parser.feed("<doc>")
parser.feed("</doc>")
parser.close()
self.assertEquals(parser.getSystemId(), None)
self.assertEquals(parser.getPublicId(), None)
self.assertEquals(parser.getLineNumber(), 1)
def test_expat_locator_withinfo(self):
result = StringIO()
xmlgen = XMLGenerator(result)
parser = create_parser()
parser.setContentHandler(xmlgen)
parser.parse(findfile("test.xml"))
self.assertEquals(parser.getSystemId(), findfile("test.xml"))
self.assertEquals(parser.getPublicId(), None)
# =========================================================================== # ===========================================================================
# #
# error reporting # error reporting
# #
# =========================================================================== # ===========================================================================
def test_expat_inpsource_location(): class ErrorReportingTest(unittest.TestCase):
parser = create_parser() def test_expat_inpsource_location(self):
parser.setContentHandler(ContentHandler()) # do nothing parser = create_parser()
source = InputSource() parser.setContentHandler(ContentHandler()) # do nothing
source.setByteStream(StringIO("<foo bar foobar>")) #ill-formed source = InputSource()
name = "a file name" source.setByteStream(StringIO("<foo bar foobar>")) #ill-formed
source.setSystemId(name) name = "a file name"
try: source.setSystemId(name)
parser.parse(source) try:
except SAXException, e: parser.parse(source)
return e.getSystemId() == name self.fail()
except SAXException, e:
def test_expat_incomplete(): self.assertEquals(e.getSystemId(), name)
parser = create_parser()
parser.setContentHandler(ContentHandler()) # do nothing def test_expat_incomplete(self):
try: parser = create_parser()
parser.parse(StringIO("<foo>")) parser.setContentHandler(ContentHandler()) # do nothing
except SAXParseException: self.assertRaises(SAXParseException, parser.parse, StringIO("<foo>"))
return 1 # ok, error found
else: def test_sax_parse_exception_str(self):
return 0 # pass various values from a locator to the SAXParseException to
# make sure that the __str__() doesn't fall apart when None is
def test_sax_parse_exception_str(): # passed instead of an integer line and column number
# pass various values from a locator to the SAXParseException to #
# make sure that the __str__() doesn't fall apart when None is # use "normal" values for the locator:
# passed instead of an integer line and column number str(SAXParseException("message", None,
# self.DummyLocator(1, 1)))
# use "normal" values for the locator: # use None for the line number:
str(SAXParseException("message", None, str(SAXParseException("message", None,
DummyLocator(1, 1))) self.DummyLocator(None, 1)))
# use None for the line number: # use None for the column number:
str(SAXParseException("message", None, str(SAXParseException("message", None,
DummyLocator(None, 1))) self.DummyLocator(1, None)))
# use None for the column number: # use None for both:
str(SAXParseException("message", None, str(SAXParseException("message", None,
DummyLocator(1, None))) self.DummyLocator(None, None)))
# use None for both:
str(SAXParseException("message", None, class DummyLocator:
DummyLocator(None, None))) def __init__(self, lineno, colno):
return 1 self._lineno = lineno
self._colno = colno
class DummyLocator:
def __init__(self, lineno, colno): def getPublicId(self):
self._lineno = lineno return "pubid"
self._colno = colno
def getSystemId(self):
def getPublicId(self): return "sysid"
return "pubid"
def getLineNumber(self):
def getSystemId(self): return self._lineno
return "sysid"
def getColumnNumber(self):
def getLineNumber(self): return self._colno
return self._lineno
def getColumnNumber(self):
return self._colno
# =========================================================================== # ===========================================================================
# #
...@@ -571,218 +606,91 @@ class DummyLocator: ...@@ -571,218 +606,91 @@ class DummyLocator:
# #
# =========================================================================== # ===========================================================================
# ===== AttributesImpl class XmlReaderTest(XmlTestBase):
def verify_empty_attrs(attrs): # ===== AttributesImpl
try: def test_attrs_empty(self):
attrs.getValue("attr") self.verify_empty_attrs(AttributesImpl({}))
gvk = 0
except KeyError: def test_attrs_wattr(self):
gvk = 1 self.verify_attrs_wattr(AttributesImpl({"attr" : "val"}))
try: def test_nsattrs_empty(self):
attrs.getValueByQName("attr") self.verify_empty_nsattrs(AttributesNSImpl({}, {}))
gvqk = 0
except KeyError: def test_nsattrs_wattr(self):
gvqk = 1 attrs = AttributesNSImpl({(ns_uri, "attr") : "val"},
{(ns_uri, "attr") : "ns:attr"})
try:
attrs.getNameByQName("attr") self.assertEquals(attrs.getLength(), 1)
gnqk = 0 self.assertEquals(attrs.getNames(), [(ns_uri, "attr")])
except KeyError: self.assertEquals(attrs.getQNames(), ["ns:attr"])
gnqk = 1 self.assertEquals(len(attrs), 1)
self.assertTrue(attrs.has_key((ns_uri, "attr")))
try: self.assertEquals(attrs.keys(), [(ns_uri, "attr")])
attrs.getQNameByName("attr") self.assertEquals(attrs.get((ns_uri, "attr")), "val")
gqnk = 0 self.assertEquals(attrs.get((ns_uri, "attr"), 25), "val")
except KeyError: self.assertEquals(attrs.items(), [((ns_uri, "attr"), "val")])
gqnk = 1 self.assertEquals(attrs.values(), ["val"])
self.assertEquals(attrs.getValue((ns_uri, "attr")), "val")
try: self.assertEquals(attrs.getValueByQName("ns:attr"), "val")
attrs["attr"] self.assertEquals(attrs.getNameByQName("ns:attr"), (ns_uri, "attr"))
gik = 0 self.assertEquals(attrs[(ns_uri, "attr")], "val")
except KeyError: self.assertEquals(attrs.getQNameByName((ns_uri, "attr")), "ns:attr")
gik = 1
return attrs.getLength() == 0 and \ # During the development of Python 2.5, an attempt to move the "xml"
attrs.getNames() == [] and \ # package implementation to a new package ("xmlcore") proved painful.
attrs.getQNames() == [] and \ # The goal of this change was to allow applications to be able to
len(attrs) == 0 and \ # obtain and rely on behavior in the standard library implementation
not attrs.has_key("attr") and \ # of the XML support without needing to be concerned about the
attrs.keys() == [] and \ # availability of the PyXML implementation.
attrs.get("attrs") is None and \ #
attrs.get("attrs", 25) == 25 and \ # While the existing import hackery in Lib/xml/__init__.py can cause
attrs.items() == [] and \ # PyXML's _xmlpus package to supplant the "xml" package, that only
attrs.values() == [] and \ # works because either implementation uses the "xml" package name for
gvk and gvqk and gnqk and gik and gqnk # imports.
#
def verify_attrs_wattr(attrs): # The move resulted in a number of problems related to the fact that
return attrs.getLength() == 1 and \ # the import machinery's "package context" is based on the name that's
attrs.getNames() == ["attr"] and \ # being imported rather than the __name__ of the actual package
attrs.getQNames() == ["attr"] and \ # containment; it wasn't possible for the "xml" package to be replaced
len(attrs) == 1 and \ # by a simple module that indirected imports to the "xmlcore" package.
attrs.has_key("attr") and \ #
attrs.keys() == ["attr"] and \ # The following two tests exercised bugs that were introduced in that
attrs.get("attr") == "val" and \ # attempt. Keeping these tests around will help detect problems with
attrs.get("attr", 25) == "val" and \ # other attempts to provide reliable access to the standard library's
attrs.items() == [("attr", "val")] and \ # implementation of the XML support.
attrs.values() == ["val"] and \
attrs.getValue("attr") == "val" and \ def test_sf_1511497(self):
attrs.getValueByQName("attr") == "val" and \ # Bug report: http://www.python.org/sf/1511497
attrs.getNameByQName("attr") == "attr" and \ import sys
attrs["attr"] == "val" and \ old_modules = sys.modules.copy()
attrs.getQNameByName("attr") == "attr" for modname in sys.modules.keys():
if modname.startswith("xml."):
def test_attrs_empty(): del sys.modules[modname]
return verify_empty_attrs(AttributesImpl({})) try:
import xml.sax.expatreader
def test_attrs_wattr(): module = xml.sax.expatreader
return verify_attrs_wattr(AttributesImpl({"attr" : "val"})) self.assertEquals(module.__name__, "xml.sax.expatreader")
finally:
# ===== AttributesImpl sys.modules.update(old_modules)
def verify_empty_nsattrs(attrs): def test_sf_1513611(self):
try: # Bug report: http://www.python.org/sf/1513611
attrs.getValue((ns_uri, "attr")) sio = StringIO("invalid")
gvk = 0 parser = make_parser()
except KeyError: from xml.sax import SAXParseException
gvk = 1 self.assertRaises(SAXParseException, parser.parse, sio)
try:
attrs.getValueByQName("ns:attr") def unittest_main():
gvqk = 0 run_unittest(MakeParserTest,
except KeyError: SaxutilsTest,
gvqk = 1 XmlgenTest,
ExpatReaderTest,
try: ErrorReportingTest,
attrs.getNameByQName("ns:attr") XmlReaderTest)
gnqk = 0
except KeyError: if __name__ == "__main__":
gnqk = 1 unittest_main()
try:
attrs.getQNameByName((ns_uri, "attr"))
gqnk = 0
except KeyError:
gqnk = 1
try:
attrs[(ns_uri, "attr")]
gik = 0
except KeyError:
gik = 1
return attrs.getLength() == 0 and \
attrs.getNames() == [] and \
attrs.getQNames() == [] and \
len(attrs) == 0 and \
not attrs.has_key((ns_uri, "attr")) and \
attrs.keys() == [] and \
attrs.get((ns_uri, "attr")) is None and \
attrs.get((ns_uri, "attr"), 25) == 25 and \
attrs.items() == [] and \
attrs.values() == [] and \
gvk and gvqk and gnqk and gik and gqnk
def test_nsattrs_empty():
return verify_empty_nsattrs(AttributesNSImpl({}, {}))
def test_nsattrs_wattr():
attrs = AttributesNSImpl({(ns_uri, "attr") : "val"},
{(ns_uri, "attr") : "ns:attr"})
return attrs.getLength() == 1 and \
attrs.getNames() == [(ns_uri, "attr")] and \
attrs.getQNames() == ["ns:attr"] and \
len(attrs) == 1 and \
attrs.has_key((ns_uri, "attr")) and \
attrs.keys() == [(ns_uri, "attr")] and \
attrs.get((ns_uri, "attr")) == "val" and \
attrs.get((ns_uri, "attr"), 25) == "val" and \
attrs.items() == [((ns_uri, "attr"), "val")] and \
attrs.values() == ["val"] and \
attrs.getValue((ns_uri, "attr")) == "val" and \
attrs.getValueByQName("ns:attr") == "val" and \
attrs.getNameByQName("ns:attr") == (ns_uri, "attr") and \
attrs[(ns_uri, "attr")] == "val" and \
attrs.getQNameByName((ns_uri, "attr")) == "ns:attr"
# During the development of Python 2.5, an attempt to move the "xml"
# package implementation to a new package ("xmlcore") proved painful.
# The goal of this change was to allow applications to be able to
# obtain and rely on behavior in the standard library implementation
# of the XML support without needing to be concerned about the
# availability of the PyXML implementation.
#
# While the existing import hackery in Lib/xml/__init__.py can cause
# PyXML's _xmlpus package to supplant the "xml" package, that only
# works because either implementation uses the "xml" package name for
# imports.
#
# The move resulted in a number of problems related to the fact that
# the import machinery's "package context" is based on the name that's
# being imported rather than the __name__ of the actual package
# containment; it wasn't possible for the "xml" package to be replaced
# by a simple module that indirected imports to the "xmlcore" package.
#
# The following two tests exercised bugs that were introduced in that
# attempt. Keeping these tests around will help detect problems with
# other attempts to provide reliable access to the standard library's
# implementation of the XML support.
def test_sf_1511497():
# Bug report: http://www.python.org/sf/1511497
import sys
old_modules = sys.modules.copy()
for modname in sys.modules.keys():
if modname.startswith("xml."):
del sys.modules[modname]
try:
import xml.sax.expatreader
module = xml.sax.expatreader
return module.__name__ == "xml.sax.expatreader"
finally:
sys.modules.update(old_modules)
def test_sf_1513611():
# Bug report: http://www.python.org/sf/1513611
sio = StringIO("invalid")
parser = make_parser()
from xml.sax import SAXParseException
try:
parser.parse(sio)
except SAXParseException:
return True
else:
return False
# ===== Main program
def make_test_output():
parser = create_parser()
result = StringIO()
xmlgen = XMLGenerator(result)
parser.setContentHandler(xmlgen)
parser.parse(findfile("test"+os.extsep+"xml"))
outf = open(findfile("test"+os.extsep+"xml"+os.extsep+"out"), "w")
outf.write(result.getvalue())
outf.close()
items = locals().items()
items.sort()
for (name, value) in items:
if name[ : 5] == "test_":
confirm(value(), name)
# We delete the items variable so that the assignment to items above
# doesn't pick up the old value of items (which messes with attempts
# to find reference leaks).
del items
if verbose:
print "%d tests, %d failures" % (tests, len(failures))
if failures:
raise TestFailed("%d of %d tests failed: %s"
% (len(failures), tests, ", ".join(failures)))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment