Initial import to Tizen
[profile/ivi/python-twisted.git] / twisted / web / test / test_domhelpers.py
1 # -*- test-case-name: twisted.web.test.test_domhelpers -*-
2 # Copyright (c) Twisted Matrix Laboratories.
3 # See LICENSE for details.
4
5 """
6 Specific tests for (some of) the methods in L{twisted.web.domhelpers}.
7 """
8
9 from xml.dom import minidom
10
11 from twisted.trial.unittest import TestCase
12
13 from twisted.web import microdom
14
15 from twisted.web import domhelpers
16
17
18 class DOMHelpersTestsMixin:
19     """
20     A mixin for L{TestCase} subclasses which defines test methods for
21     domhelpers functionality based on a DOM creation function provided by a
22     subclass.
23     """
24     dom = None
25
26     def test_getElementsByTagName(self):
27         doc1 = self.dom.parseString('<foo/>')
28         actual=domhelpers.getElementsByTagName(doc1, 'foo')[0].nodeName
29         expected='foo'
30         self.assertEqual(actual, expected)
31         el1=doc1.documentElement
32         actual=domhelpers.getElementsByTagName(el1, 'foo')[0].nodeName
33         self.assertEqual(actual, expected)
34
35         doc2_xml='<a><foo in="a"/><b><foo in="b"/></b><c><foo in="c"/></c><foo in="d"/><foo in="ef"/><g><foo in="g"/><h><foo in="h"/></h></g></a>'
36         doc2 = self.dom.parseString(doc2_xml)
37         tag_list=domhelpers.getElementsByTagName(doc2, 'foo')
38         actual=''.join([node.getAttribute('in') for node in tag_list])
39         expected='abcdefgh'
40         self.assertEqual(actual, expected)
41         el2=doc2.documentElement
42         tag_list=domhelpers.getElementsByTagName(el2, 'foo')
43         actual=''.join([node.getAttribute('in') for node in tag_list])
44         self.assertEqual(actual, expected)
45
46         doc3_xml='''
47 <a><foo in="a"/>
48     <b><foo in="b"/>
49         <d><foo in="d"/>
50             <g><foo in="g"/></g>
51             <h><foo in="h"/></h>
52         </d>
53         <e><foo in="e"/>
54             <i><foo in="i"/></i>
55         </e>
56     </b>
57     <c><foo in="c"/>
58         <f><foo in="f"/>
59             <j><foo in="j"/></j>
60         </f>
61     </c>
62 </a>'''
63         doc3 = self.dom.parseString(doc3_xml)
64         tag_list=domhelpers.getElementsByTagName(doc3, 'foo')
65         actual=''.join([node.getAttribute('in') for node in tag_list])
66         expected='abdgheicfj'
67         self.assertEqual(actual, expected)
68         el3=doc3.documentElement
69         tag_list=domhelpers.getElementsByTagName(el3, 'foo')
70         actual=''.join([node.getAttribute('in') for node in tag_list])
71         self.assertEqual(actual, expected)
72
73         doc4_xml='<foo><bar></bar><baz><foo/></baz></foo>'
74         doc4 = self.dom.parseString(doc4_xml)
75         actual=domhelpers.getElementsByTagName(doc4, 'foo')
76         root=doc4.documentElement
77         expected=[root, root.childNodes[-1].childNodes[0]]
78         self.assertEqual(actual, expected)
79         actual=domhelpers.getElementsByTagName(root, 'foo')
80         self.assertEqual(actual, expected)
81
82
83     def test_gatherTextNodes(self):
84         doc1 = self.dom.parseString('<a>foo</a>')
85         actual=domhelpers.gatherTextNodes(doc1)
86         expected='foo'
87         self.assertEqual(actual, expected)
88         actual=domhelpers.gatherTextNodes(doc1.documentElement)
89         self.assertEqual(actual, expected)
90
91         doc2_xml='<a>a<b>b</b><c>c</c>def<g>g<h>h</h></g></a>'
92         doc2 = self.dom.parseString(doc2_xml)
93         actual=domhelpers.gatherTextNodes(doc2)
94         expected='abcdefgh'
95         self.assertEqual(actual, expected)
96         actual=domhelpers.gatherTextNodes(doc2.documentElement)
97         self.assertEqual(actual, expected)
98
99         doc3_xml=('<a>a<b>b<d>d<g>g</g><h>h</h></d><e>e<i>i</i></e></b>' +
100                   '<c>c<f>f<j>j</j></f></c></a>')
101         doc3 = self.dom.parseString(doc3_xml)
102         actual=domhelpers.gatherTextNodes(doc3)
103         expected='abdgheicfj'
104         self.assertEqual(actual, expected)
105         actual=domhelpers.gatherTextNodes(doc3.documentElement)
106         self.assertEqual(actual, expected)
107
108     def test_clearNode(self):
109         doc1 = self.dom.parseString('<a><b><c><d/></c></b></a>')
110         a_node=doc1.documentElement
111         domhelpers.clearNode(a_node)
112         self.assertEqual(
113             a_node.toxml(),
114             self.dom.Element('a').toxml())
115
116         doc2 = self.dom.parseString('<a><b><c><d/></c></b></a>')
117         b_node=doc2.documentElement.childNodes[0]
118         domhelpers.clearNode(b_node)
119         actual=doc2.documentElement.toxml()
120         expected = self.dom.Element('a')
121         expected.appendChild(self.dom.Element('b'))
122         self.assertEqual(actual, expected.toxml())
123
124
125     def test_get(self):
126         doc1 = self.dom.parseString('<a><b id="bar"/><c class="foo"/></a>')
127         node=domhelpers.get(doc1, "foo")
128         actual=node.toxml()
129         expected = self.dom.Element('c')
130         expected.setAttribute('class', 'foo')
131         self.assertEqual(actual, expected.toxml())
132
133         node=domhelpers.get(doc1, "bar")
134         actual=node.toxml()
135         expected = self.dom.Element('b')
136         expected.setAttribute('id', 'bar')
137         self.assertEqual(actual, expected.toxml())
138
139         self.assertRaises(domhelpers.NodeLookupError, 
140                           domhelpers.get, 
141                           doc1, 
142                           "pzork")
143
144     def test_getIfExists(self):
145         doc1 = self.dom.parseString('<a><b id="bar"/><c class="foo"/></a>')
146         node=domhelpers.getIfExists(doc1, "foo")
147         actual=node.toxml()
148         expected = self.dom.Element('c')
149         expected.setAttribute('class', 'foo')
150         self.assertEqual(actual, expected.toxml())
151
152         node=domhelpers.getIfExists(doc1, "pzork")
153         self.assertIdentical(node, None)
154
155
156     def test_getAndClear(self):
157         doc1 = self.dom.parseString('<a><b id="foo"><c></c></b></a>')
158         node=domhelpers.getAndClear(doc1, "foo")
159         actual=node.toxml()
160         expected = self.dom.Element('b')
161         expected.setAttribute('id', 'foo')
162         self.assertEqual(actual, expected.toxml())
163
164
165     def test_locateNodes(self):
166         doc1 = self.dom.parseString('<a><b foo="olive"><c foo="olive"/></b><d foo="poopy"/></a>')
167         node_list=domhelpers.locateNodes(
168             doc1.childNodes, 'foo', 'olive', noNesting=1)
169         actual=''.join([node.toxml() for node in node_list])
170         expected = self.dom.Element('b')
171         expected.setAttribute('foo', 'olive')
172         c = self.dom.Element('c')
173         c.setAttribute('foo', 'olive')
174         expected.appendChild(c)
175
176         self.assertEqual(actual, expected.toxml())
177
178         node_list=domhelpers.locateNodes(
179             doc1.childNodes, 'foo', 'olive', noNesting=0)
180         actual=''.join([node.toxml() for node in node_list])
181         self.assertEqual(actual, expected.toxml() + c.toxml())
182
183
184     def test_getParents(self):
185         doc1 = self.dom.parseString('<a><b><c><d/></c><e/></b><f/></a>')
186         node_list = domhelpers.getParents(
187             doc1.childNodes[0].childNodes[0].childNodes[0])
188         actual = ''.join([node.tagName for node in node_list
189                           if hasattr(node, 'tagName')])
190         self.assertEqual(actual, 'cba')
191
192
193     def test_findElementsWithAttribute(self):
194         doc1 = self.dom.parseString('<a foo="1"><b foo="2"/><c foo="1"/><d/></a>')
195         node_list = domhelpers.findElementsWithAttribute(doc1, 'foo')
196         actual = ''.join([node.tagName for node in node_list])
197         self.assertEqual(actual, 'abc')
198
199         node_list = domhelpers.findElementsWithAttribute(doc1, 'foo', '1')
200         actual = ''.join([node.tagName for node in node_list])
201         self.assertEqual(actual, 'ac')
202
203
204     def test_findNodesNamed(self):
205         doc1 = self.dom.parseString('<doc><foo/><bar/><foo>a</foo></doc>')
206         node_list = domhelpers.findNodesNamed(doc1, 'foo')
207         actual = len(node_list)
208         self.assertEqual(actual, 2)
209
210     # NOT SURE WHAT THESE ARE SUPPOSED TO DO..
211     # def test_RawText  FIXME
212     # def test_superSetAttribute FIXME
213     # def test_superPrependAttribute FIXME
214     # def test_superAppendAttribute FIXME
215     # def test_substitute FIXME
216
217     def test_escape(self):
218         j='this string " contains many & characters> xml< won\'t like'
219         expected='this string &quot; contains many &amp; characters&gt; xml&lt; won\'t like'
220         self.assertEqual(domhelpers.escape(j), expected)
221
222     def test_unescape(self):
223         j='this string &quot; has &&amp; entities &gt; &lt; and some characters xml won\'t like<'
224         expected='this string " has && entities > < and some characters xml won\'t like<'
225         self.assertEqual(domhelpers.unescape(j), expected)
226
227
228     def test_getNodeText(self):
229         """
230         L{getNodeText} returns the concatenation of all the text data at or
231         beneath the node passed to it.
232         """
233         node = self.dom.parseString('<foo><bar>baz</bar><bar>quux</bar></foo>')
234         self.assertEqual(domhelpers.getNodeText(node), "bazquux")
235
236
237
238 class MicroDOMHelpersTests(DOMHelpersTestsMixin, TestCase):
239     dom = microdom
240
241     def test_gatherTextNodesDropsWhitespace(self):
242         """
243         Microdom discards whitespace-only text nodes, so L{gatherTextNodes}
244         returns only the text from nodes which had non-whitespace characters.
245         """
246         doc4_xml='''<html>
247   <head>
248   </head>
249   <body>
250     stuff
251   </body>
252 </html>
253 '''
254         doc4 = self.dom.parseString(doc4_xml)
255         actual = domhelpers.gatherTextNodes(doc4)
256         expected = '\n    stuff\n  '
257         self.assertEqual(actual, expected)
258         actual = domhelpers.gatherTextNodes(doc4.documentElement)
259         self.assertEqual(actual, expected)
260
261
262     def test_textEntitiesNotDecoded(self):
263         """
264         Microdom does not decode entities in text nodes.
265         """
266         doc5_xml='<x>Souffl&amp;</x>'
267         doc5 = self.dom.parseString(doc5_xml)
268         actual=domhelpers.gatherTextNodes(doc5)
269         expected='Souffl&amp;'
270         self.assertEqual(actual, expected)
271         actual=domhelpers.gatherTextNodes(doc5.documentElement)
272         self.assertEqual(actual, expected)
273
274
275
276 class MiniDOMHelpersTests(DOMHelpersTestsMixin, TestCase):
277     dom = minidom
278
279     def test_textEntitiesDecoded(self):
280         """
281         Minidom does decode entities in text nodes.
282         """
283         doc5_xml='<x>Souffl&amp;</x>'
284         doc5 = self.dom.parseString(doc5_xml)
285         actual=domhelpers.gatherTextNodes(doc5)
286         expected='Souffl&'
287         self.assertEqual(actual, expected)
288         actual=domhelpers.gatherTextNodes(doc5.documentElement)
289         self.assertEqual(actual, expected)
290
291
292     def test_getNodeUnicodeText(self):
293         """
294         L{domhelpers.getNodeText} returns a C{unicode} string when text
295         nodes are represented in the DOM with unicode, whether or not there
296         are non-ASCII characters present.
297         """
298         node = self.dom.parseString("<foo>bar</foo>")
299         text = domhelpers.getNodeText(node)
300         self.assertEqual(text, u"bar")
301         self.assertIsInstance(text, unicode)
302
303         node = self.dom.parseString(u"<foo>\N{SNOWMAN}</foo>".encode('utf-8'))
304         text = domhelpers.getNodeText(node)
305         self.assertEqual(text, u"\N{SNOWMAN}")
306         self.assertIsInstance(text, unicode)