1
# Copyright (c) 2001-2005 Twisted Matrix Laboratories.
2
# See LICENSE for details.
5
from twisted.trial import unittest
8
from twisted.words.xish.domish import Element
9
from twisted.words.xish.xpath import XPathQuery
10
from twisted.words.xish import xpath
12
class XPathTest(unittest.TestCase):
15
# <foo xmlns='testns' attrib1='value1' attrib3="user@host/resource">
23
# <bar attrib2="value2">
29
# <bar attrib4='value4' attrib5='value5'>
33
# <bar attrib4='value4' attrib5='value4'>
37
# <bar attrib4='value4' attrib5='value6'/>
39
self.e = Element(("testns", "foo"))
40
self.e["attrib1"] = "value1"
41
self.e["attrib3"] = "user@host/resource"
42
self.e.addContent("somecontent")
43
self.bar1 = self.e.addElement("bar")
44
self.subfoo = self.bar1.addElement("foo")
45
self.gar1 = self.subfoo.addElement("gar")
46
self.gar1.addContent("DEF")
47
self.e.addContent("somemorecontent")
48
self.bar2 = self.e.addElement("bar")
49
self.bar2["attrib2"] = "value2"
50
self.bar3 = self.bar2.addElement("bar")
51
self.subfoo2 = self.bar3.addElement("foo")
52
self.gar2 = self.bar3.addElement("gar")
53
self.gar2.addContent("ABC")
54
self.bar4 = self.e.addElement("bar")
55
self.bar5 = self.e.addElement("bar")
56
self.bar5["attrib4"] = "value4"
57
self.bar5["attrib5"] = "value5"
58
self.subfoo3 = self.bar5.addElement("foo")
59
self.gar3 = self.bar5.addElement("gar")
60
self.gar3.addContent("JKL")
61
self.bar6 = self.e.addElement("bar")
62
self.bar6["attrib4"] = "value4"
63
self.bar6["attrib5"] = "value4"
64
self.subfoo4 = self.bar6.addElement("foo")
65
self.gar4 = self.bar6.addElement("gar")
66
self.gar4.addContent("MNO")
67
self.bar7 = self.e.addElement("bar")
68
self.bar7["attrib4"] = "value4"
69
self.bar7["attrib5"] = "value6"
71
def test_staticMethods(self):
73
Test basic operation of the static methods.
75
self.assertEquals(xpath.matches("/foo/bar", self.e),
77
self.assertEquals(xpath.queryForNodes("/foo/bar", self.e),
78
[self.bar1, self.bar2, self.bar4,
79
self.bar5, self.bar6, self.bar7])
80
self.assertEquals(xpath.queryForString("/foo", self.e),
82
self.assertEquals(xpath.queryForStringList("/foo", self.e),
83
["somecontent", "somemorecontent"])
85
def test_locationFooBar(self):
87
Test matching foo with child bar.
89
xp = XPathQuery("/foo/bar")
90
self.assertEquals(xp.matches(self.e), 1)
92
def test_locationFooBarFoo(self):
94
Test finding foos at the second level.
96
xp = XPathQuery("/foo/bar/foo")
97
self.assertEquals(xp.matches(self.e), 1)
98
self.assertEquals(xp.queryForNodes(self.e), [self.subfoo,
102
def test_locationNoBar3(self):
104
Test not finding bar3.
106
xp = XPathQuery("/foo/bar3")
107
self.assertEquals(xp.matches(self.e), 0)
109
def test_locationAllChilds(self):
111
Test finding childs of foo.
113
xp = XPathQuery("/foo/*")
114
self.assertEquals(xp.matches(self.e), True)
115
self.assertEquals(xp.queryForNodes(self.e), [self.bar1, self.bar2,
116
self.bar4, self.bar5,
117
self.bar6, self.bar7])
119
def test_attribute(self):
121
Test matching foo with attribute.
123
xp = XPathQuery("/foo[@attrib1]")
124
self.assertEquals(xp.matches(self.e), True)
126
def test_attributeWithValueAny(self):
128
Test find nodes with attribute having value.
130
xp = XPathQuery("/foo/*[@attrib2='value2']")
131
self.assertEquals(xp.matches(self.e), True)
132
self.assertEquals(xp.queryForNodes(self.e), [self.bar2])
134
def test_position(self):
136
Test finding element at position.
138
xp = XPathQuery("/foo/bar[2]")
139
self.assertEquals(xp.matches(self.e), 1)
140
self.assertEquals(xp.queryForNodes(self.e), [self.bar1])
142
test_position.todo = "XPath queries with position are not working."
144
def test_namespaceFound(self):
146
Test matching node with namespace.
148
xp = XPathQuery("/foo[@xmlns='testns']/bar")
149
self.assertEquals(xp.matches(self.e), 1)
151
def test_namespaceNotFound(self):
153
Test not matching node with wrong namespace.
155
xp = XPathQuery("/foo[@xmlns='badns']/bar2")
156
self.assertEquals(xp.matches(self.e), 0)
158
def test_attributeWithValue(self):
160
Test matching node with attribute having value.
162
xp = XPathQuery("/foo[@attrib1='value1']")
163
self.assertEquals(xp.matches(self.e), 1)
165
def test_queryForString(self):
167
Test for queryForString and queryForStringList.
169
xp = XPathQuery("/foo")
170
self.assertEquals(xp.queryForString(self.e), "somecontent")
171
self.assertEquals(xp.queryForStringList(self.e),
172
["somecontent", "somemorecontent"])
174
def test_queryForNodes(self):
178
xp = XPathQuery("/foo/bar")
179
self.assertEquals(xp.queryForNodes(self.e), [self.bar1, self.bar2,
180
self.bar4, self.bar5,
181
self.bar6, self.bar7])
183
def test_textCondition(self):
185
Test matching a node with given text.
187
xp = XPathQuery("/foo[text() = 'somecontent']")
188
self.assertEquals(xp.matches(self.e), True)
190
def test_textNotOperator(self):
192
Test for not operator.
194
xp = XPathQuery("/foo[not(@nosuchattrib)]")
195
self.assertEquals(xp.matches(self.e), True)
197
def test_anyLocationAndText(self):
199
Test finding any nodes named gar and getting their text contents.
201
xp = XPathQuery("//gar")
202
self.assertEquals(xp.matches(self.e), True)
203
self.assertEquals(xp.queryForNodes(self.e), [self.gar1, self.gar2,
204
self.gar3, self.gar4])
205
self.assertEquals(xp.queryForStringList(self.e), ["DEF", "ABC",
208
def test_anyLocation(self):
210
Test finding any nodes named bar.
212
xp = XPathQuery("//bar")
213
self.assertEquals(xp.matches(self.e), True)
214
self.assertEquals(xp.queryForNodes(self.e), [self.bar1, self.bar2,
215
self.bar3, self.bar4,
216
self.bar5, self.bar6,
219
def test_anyLocationQueryForString(self):
221
L{XPathQuery.queryForString} should raise a L{NotImplementedError}
224
xp = XPathQuery("//bar")
225
self.assertRaises(NotImplementedError, xp.queryForString, None)
227
def test_andOperator(self):
229
Test boolean and operator in condition.
231
xp = XPathQuery("//bar[@attrib4='value4' and @attrib5='value5']")
232
self.assertEquals(xp.matches(self.e), True)
233
self.assertEquals(xp.queryForNodes(self.e), [self.bar5])
235
def test_orOperator(self):
237
Test boolean or operator in condition.
239
xp = XPathQuery("//bar[@attrib5='value4' or @attrib5='value5']")
240
self.assertEquals(xp.matches(self.e), True)
241
self.assertEquals(xp.queryForNodes(self.e), [self.bar5, self.bar6])
243
def test_booleanOperatorsParens(self):
245
Test multiple boolean operators in condition with parens.
247
xp = XPathQuery("""//bar[@attrib4='value4' and
248
(@attrib5='value4' or @attrib5='value6')]""")
249
self.assertEquals(xp.matches(self.e), True)
250
self.assertEquals(xp.queryForNodes(self.e), [self.bar6, self.bar7])
252
def test_booleanOperatorsNoParens(self):
254
Test multiple boolean operators in condition without parens.
256
xp = XPathQuery("""//bar[@attrib5='value4' or
258
@attrib5='value6']""")
259
self.assertEquals(xp.matches(self.e), True)
260
self.assertEquals(xp.queryForNodes(self.e), [self.bar5, self.bar6, self.bar7])