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