3.1 --- a/libxml2dom/xmlrpc.py Fri Sep 12 01:03:56 2008 +0200
3.2 +++ b/libxml2dom/xmlrpc.py Sun Sep 14 02:30:58 2008 +0200
3.3 @@ -25,7 +25,13 @@
3.4 The sending and receiving of XML-RPC messages can be done using traditional HTTP
3.5 libraries.
3.6
3.7 -See tests/xmlrpc_test.py for more details.
3.8 +See tests/test_xmlrpc_parse.py for more details.
3.9 +
3.10 +Useful properties:
3.11 +
3.12 + * container - returns the actual value element containing transmitted data
3.13 + * contents - returns the converted data from within a container or a
3.14 + container object
3.15 """
3.16
3.17 import libxml2dom
3.18 @@ -33,6 +39,7 @@
3.19 from libxml2dom.macrolib import \
3.20 createDocument as Node_createDocument
3.21 import datetime
3.22 +import xml.dom
3.23
3.24 # Node classes.
3.25
3.26 @@ -41,12 +48,78 @@
3.27 "Convenience modifications to nodes specific to libxml2dom.xmlrpc."
3.28
3.29 def add_or_replace_element(self, new_element):
3.30 +
3.31 + """
3.32 + Add or replace the given 'new_element', using its localName to find any
3.33 + element to be replaced.
3.34 + """
3.35 +
3.36 elements = self.xpath(new_element.localName)
3.37 if elements:
3.38 self.replaceChild(new_element, elements[0])
3.39 else:
3.40 self.appendChild(new_element)
3.41
3.42 + def serialise_value(self, parent, value):
3.43 +
3.44 + "Serialise, under the 'parent', the given 'value' object."
3.45 +
3.46 + if isinstance(value, (str, int, float, bool)):
3.47 + valueElement = parent.createValue(typenames[value.__class__.__name__], 1)
3.48 + valueElement.container.value = str(value)
3.49 +
3.50 + elif isinstance(value, datetime.datetime):
3.51 + valueElement = parent.createValue("dateTime.iso8601", 1)
3.52 + valueElement.container.value = value.strftime("%Y%m%dT%H:%M:%S")
3.53 +
3.54 + elif isinstance(value, (tuple, list)):
3.55 + array = parent.createValue("array", 1).container
3.56 + dataElement = array.createData(1)
3.57 + for v in value:
3.58 + self.serialise_value(dataElement, v)
3.59 +
3.60 + elif isinstance(value, dict):
3.61 + struct = parent.createValue("struct", 1).container
3.62 + for k, v in value.items():
3.63 + member = struct.createMember(1)
3.64 + member.memberName = str(k)
3.65 + self.serialise_value(member, v)
3.66 +
3.67 + else:
3.68 + raise ValueError, "Value %r cannot be serialised." % value
3.69 +
3.70 +class ContentEquality:
3.71 +
3.72 + "Equality testing."
3.73 +
3.74 + def __eq__(self, other):
3.75 + if hasattr(other, "contents"):
3.76 + return self.contents == other.contents
3.77 + else:
3.78 + return self.contents == other
3.79 +
3.80 + def __ne__(self, other):
3.81 + return not self.__eq__(other)
3.82 +
3.83 +class SequenceEquality:
3.84 +
3.85 + "Sequence equality testing."
3.86 +
3.87 + def __eq__(self, other):
3.88 + for i, j in map(None, self, other):
3.89 + if i != j:
3.90 + return False
3.91 + return True
3.92 +
3.93 + def __ne__(self, other):
3.94 + return not self.__eq__(other)
3.95 +
3.96 + def __len__(self):
3.97 + return len(self.values())
3.98 +
3.99 + def __getitem__(self, i):
3.100 + return self.values()[i]
3.101 +
3.102 class XMLRPCElement(XMLRPCNode):
3.103
3.104 "An XML-RPC element."
3.105 @@ -110,9 +183,21 @@
3.106 self.methodNameElement.value = name
3.107
3.108 def _parameterValues(self):
3.109 - return [value.container.contents for value in self.xpath("./params/param/value")]
3.110 + if self.params:
3.111 + return self.params.values()
3.112 + else:
3.113 + return None
3.114 +
3.115 + def _setParameterValues(self, values):
3.116 + params = self.createParameters(1)
3.117 + for value in values:
3.118 + param = params.createParameter(1)
3.119 + self.serialise_value(param, value)
3.120
3.121 def _parameters(self):
3.122 +
3.123 + "Return a list of the individual param elements."
3.124 +
3.125 return self.xpath("./params/param")
3.126
3.127 # Node construction methods.
3.128 @@ -139,16 +224,36 @@
3.129 params = property(_params)
3.130 methodNameElement = property(_methodNameElement)
3.131 methodName = property(_methodName, _setMethodName)
3.132 - parameterValues = property(_parameterValues)
3.133 + parameterValues = property(_parameterValues, _setParameterValues)
3.134 parameters = property(_parameters)
3.135
3.136 -class XMLRPCParametersElement(XMLRPCNode):
3.137 +class XMLRPCParametersElement(SequenceEquality, XMLRPCNode):
3.138
3.139 - "An XML-RPC parameters/params element."
3.140 + """
3.141 + An XML-RPC parameters/params element.
3.142 +
3.143 + This element behaves like a list in that values can be appended to it and
3.144 + these will be added as new parameters.
3.145 + """
3.146
3.147 def _parameters(self):
3.148 +
3.149 + "Return a list of the individual param elements."
3.150 +
3.151 return self.xpath("./param")
3.152
3.153 + # Sequence emulation.
3.154 +
3.155 + def append(self, value):
3.156 + param = self.createParameter(1)
3.157 + self.serialise_value(param, value)
3.158 +
3.159 + def values(self):
3.160 + return [value.contents for value in self.xpath("./param/value")]
3.161 +
3.162 + def __repr__(self):
3.163 + return "<XMLRPCParametersElement: %r>" % self.parameters
3.164 +
3.165 # Node construction methods.
3.166
3.167 def createParameter(self, insert=0):
3.168 @@ -159,13 +264,50 @@
3.169
3.170 parameters = property(_parameters)
3.171
3.172 -class XMLRPCParameterElement(XMLRPCNode):
3.173 +class XMLRPCParameterElement(ContentEquality, XMLRPCNode):
3.174 +
3.175 + """
3.176 + An XML-RPC parameter/param element.
3.177
3.178 - "An XML-RPC parameter/param element."
3.179 + This element behaves like a list in that values can be appended to it and
3.180 + these will be added either as new elements in an existing array or struct,
3.181 + or as new elements in a new array.
3.182 + """
3.183
3.184 def _valueElement(self):
3.185 return (self.xpath("./value") or [None])[0]
3.186
3.187 + def _contents(self):
3.188 + if self.valueElement is not None:
3.189 + return self.valueElement.contents
3.190 + else:
3.191 + return self
3.192 +
3.193 + # Sequence emulation.
3.194 +
3.195 + def __len__(self):
3.196 + return len(self.values())
3.197 +
3.198 + def __getitem__(self, i):
3.199 + return self.values()[i]
3.200 +
3.201 + def append(self, value):
3.202 + if self.valueElement is None:
3.203 + self.createValue("array", 1)
3.204 + self.contents.append(value)
3.205 +
3.206 + def values(self):
3.207 + if self.contents is not self:
3.208 + return self.contents.values()
3.209 + else:
3.210 + return []
3.211 +
3.212 + def __repr__(self):
3.213 + if self.contents is self:
3.214 + return "<XMLRPCParameterElement>"
3.215 + else:
3.216 + return "<XMLRPCParameterElement: %r>" % self.contents
3.217 +
3.218 # Node construction methods.
3.219
3.220 def createValue(self, typename=None, insert=0):
3.221 @@ -178,10 +320,16 @@
3.222 return value
3.223
3.224 valueElement = property(_valueElement)
3.225 + contents = property(_contents)
3.226
3.227 -class XMLRPCArrayElement(XMLRPCNode):
3.228 +class XMLRPCArrayElement(SequenceEquality, XMLRPCNode):
3.229
3.230 - "An XML-RPC array element."
3.231 + """
3.232 + An XML-RPC array element.
3.233 +
3.234 + This element behaves like a list in that values can be appended to it and
3.235 + these will be added as new elements in the array.
3.236 + """
3.237
3.238 def _dataElement(self):
3.239 return (self.xpath("./data") or [None])[0]
3.240 @@ -191,23 +339,16 @@
3.241
3.242 # Sequence emulation.
3.243
3.244 - def __len__(self):
3.245 - if self.data:
3.246 - return len(self.data)
3.247 - else:
3.248 - return 0
3.249 + def append(self, value):
3.250 + if self.dataElement is None:
3.251 + self.createData(1)
3.252 + self.serialise_value(self.dataElement, value)
3.253
3.254 - def __getitem__(self, i):
3.255 - if self.data:
3.256 - return self.data[i]
3.257 - else:
3.258 - raise IndexError, i
3.259 + def values(self):
3.260 + return [v.contents for v in self.xpath("./data/value")]
3.261
3.262 - def __eq__(self, other):
3.263 - for i, j in map(None, self, other):
3.264 - if i != j:
3.265 - return False
3.266 - return True
3.267 + def __repr__(self):
3.268 + return "<XMLRPCArrayElement: %r>" % self.values()
3.269
3.270 # Node construction methods.
3.271
3.272 @@ -220,9 +361,14 @@
3.273 dataElement = property(_dataElement)
3.274 contents = property(_contents)
3.275
3.276 -class XMLRPCStructElement(XMLRPCNode):
3.277 +class XMLRPCStructElement(SequenceEquality, XMLRPCNode):
3.278
3.279 - "An XML-RPC structure element."
3.280 + """
3.281 + An XML-RPC structure element.
3.282 +
3.283 + This element behaves like a list in that values can be appended to it and
3.284 + these will be added as new (name, value) members in the structure.
3.285 + """
3.286
3.287 def _members(self):
3.288 return self.xpath("./member")
3.289 @@ -238,51 +384,77 @@
3.290 def __getitem__(self, i):
3.291 return self.members[i]
3.292
3.293 - def __eq__(self, other):
3.294 - for i, j in map(None, self, other):
3.295 - if i != j:
3.296 - return False
3.297 - return True
3.298 + def append(self, item):
3.299 + name, value = item
3.300 + member = self.createMember(1)
3.301 + member.memberName = name
3.302 + self.serialise_value(member, value)
3.303 +
3.304 + def __repr__(self):
3.305 + return "<XMLRPCStructElement: %r>" % self.items()
3.306 +
3.307 + # Dictionary emulation.
3.308 +
3.309 + def keys(self):
3.310 + return [member.memberName for member in self.members]
3.311 +
3.312 + def values(self):
3.313 + return [member.memberValue for member in self.members]
3.314 +
3.315 + def items(self):
3.316 + return [(member.memberName, member.memberValue) for member in self.members]
3.317
3.318 # Node construction methods.
3.319
3.320 def createMember(self, insert=0):
3.321 e = self.ownerDocument.createElement("member")
3.322 if insert:
3.323 - self.add_or_replace_element(e)
3.324 + self.appendChild(e)
3.325 return e
3.326
3.327 members = property(_members)
3.328 contents = property(_contents)
3.329
3.330 -class XMLRPCDataElement(XMLRPCNode):
3.331 +class XMLRPCDataElement(SequenceEquality, XMLRPCNode):
3.332 +
3.333 + """
3.334 + An XML-RPC array data element.
3.335
3.336 - "An XML-RPC array data element."
3.337 + This element behaves like a list in that values can be appended to it and
3.338 + these will be added as new elements in the array.
3.339 + """
3.340
3.341 - def _values(self):
3.342 - return self.xpath("./value")
3.343 + def _contents(self):
3.344 + return self
3.345
3.346 # Sequence emulation.
3.347
3.348 - def __len__(self):
3.349 - return len(self.values)
3.350 + def append(self, value):
3.351 + self.serialise_value(self, value)
3.352
3.353 - def __getitem__(self, i):
3.354 - return self.values[i].container.contents
3.355 + def values(self):
3.356 + return [v.contents for v in self.xpath("./value")]
3.357
3.358 # Node construction methods.
3.359
3.360 - def createValue(self, insert=0):
3.361 - e = self.ownerDocument.createElement("value")
3.362 + def createValue(self, typename=None, insert=0):
3.363 + value = self.ownerDocument.createElement("value")
3.364 + if typename is not None:
3.365 + contents = self.ownerDocument.createElement(typename)
3.366 + value.appendChild(contents)
3.367 if insert:
3.368 - self.add_or_replace_element(e)
3.369 - return e
3.370 + self.appendChild(value)
3.371 + return value
3.372
3.373 - values = property(_values)
3.374 + contents = property(_contents)
3.375
3.376 class XMLRPCMemberElement(XMLRPCNode):
3.377
3.378 - "An XML-RPC structure member element."
3.379 + """
3.380 + An XML-RPC structure member element.
3.381 +
3.382 + This element behaves like a tuple of the form (name, value).
3.383 + """
3.384
3.385 def _valueElement(self):
3.386 return (self.xpath("./value") or [None])[0]
3.387 @@ -302,6 +474,12 @@
3.388 self.appendChild(nameElement)
3.389 self.nameElement.value = name
3.390
3.391 + def _memberValue(self):
3.392 + if self.valueElement is None:
3.393 + return None
3.394 + else:
3.395 + return self.valueElement.contents
3.396 +
3.397 def _contents(self):
3.398 return self
3.399
3.400 @@ -311,11 +489,16 @@
3.401 return 2
3.402
3.403 def __getitem__(self, i):
3.404 - return (self.memberName, self.value.container.contents)[i]
3.405 + return (self.memberName, self.valueElement.contents)[i]
3.406 +
3.407 + # Equality testing.
3.408
3.409 def __eq__(self, other):
3.410 return self[0] == other[0] and self[1] == other[1]
3.411
3.412 + def __ne__(self, other):
3.413 + return not self.__eq__(other)
3.414 +
3.415 # Node construction methods.
3.416
3.417 def createName(self, insert=0):
3.418 @@ -324,18 +507,22 @@
3.419 self.add_or_replace_element(e)
3.420 return e
3.421
3.422 - def createValue(self, insert=0):
3.423 - e = self.ownerDocument.createElement("value")
3.424 + def createValue(self, typename=None, insert=0):
3.425 + value = self.ownerDocument.createElement("value")
3.426 + if typename is not None:
3.427 + contents = self.ownerDocument.createElement(typename)
3.428 + value.appendChild(contents)
3.429 if insert:
3.430 - self.add_or_replace_element(e)
3.431 - return e
3.432 + self.add_or_replace_element(value)
3.433 + return value
3.434
3.435 nameElement = property(_nameElement)
3.436 memberName = property(_memberName, _setMemberName)
3.437 + memberValue = property(_memberValue)
3.438 valueElement = property(_valueElement)
3.439 contents = property(_contents)
3.440
3.441 -class XMLRPCStringElement(XMLRPCNode):
3.442 +class XMLRPCStringElement(ContentEquality, XMLRPCNode):
3.443
3.444 "An XML-RPC string element."
3.445
3.446 @@ -353,11 +540,8 @@
3.447 def _contents(self):
3.448 return convert(self.typename, self.value)
3.449
3.450 - def __eq__(self, other):
3.451 - if hasattr(other, "contents"):
3.452 - return self.contents == other.contents
3.453 - else:
3.454 - return self.contents == other
3.455 + def __repr__(self):
3.456 + return "<%s: %r>" % (self.__class__.__name__, self.contents)
3.457
3.458 value = property(_value, _setValue)
3.459 contents = property(_contents)
3.460 @@ -368,16 +552,39 @@
3.461
3.462 pass
3.463
3.464 +class XMLRPCMethodNameElement(XMLRPCNameElement):
3.465 +
3.466 + "An XML-RPC method element."
3.467 +
3.468 + pass
3.469 +
3.470 class XMLRPCValueElement(XMLRPCStringElement):
3.471
3.472 "An XML-RPC value element."
3.473
3.474 + def _value(self):
3.475 + if self.container is self:
3.476 + return XMLRPCStringElement._value(self)
3.477 + else:
3.478 + return None
3.479 +
3.480 + def _setValue(self, value):
3.481 + if self.container is self:
3.482 + return XMLRPCStringElement._setValue(self, value)
3.483 + else:
3.484 + raise xml.dom.DOMException(xml.dom.NOT_SUPPORTED_ERR)
3.485 +
3.486 + def _contents(self):
3.487 + if self.container is self:
3.488 + return XMLRPCStringElement._contents(self)
3.489 + else:
3.490 + return self.container.contents
3.491 +
3.492 def _type(self):
3.493 - elements = self.xpath("*")
3.494 - if elements:
3.495 - return elements[0].localName
3.496 + if self.container is self:
3.497 + return "string"
3.498 else:
3.499 - return "string"
3.500 + return self.container.localName
3.501
3.502 def _setType(self, typename):
3.503 new_contents = self.ownerDocument.createElement(typename)
3.504 @@ -386,14 +593,10 @@
3.505 def _container(self):
3.506 return (self.xpath("*") or [self])[0]
3.507
3.508 + value = property(_value, _setValue)
3.509 type = property(_type, _setType)
3.510 container = property(_container)
3.511 -
3.512 -class XMLRPCMethodNameElement(XMLRPCStringElement):
3.513 -
3.514 - "An XML-RPC method element."
3.515 -
3.516 - pass
3.517 + contents = property(_contents)
3.518
3.519 class XMLRPCIntegerElement(XMLRPCStringElement):
3.520
3.521 @@ -457,7 +660,7 @@
3.522 elif s.lower() == "false":
3.523 return False
3.524 else:
3.525 - raise ValueError, "String value %s not convertable to boolean." % repr(s)
3.526 + raise ValueError, "String value %r not convertable to boolean." % s
3.527
3.528 def iso8601(s):
3.529 year, month, day, hour, minute, second = map(int, (s[:4], s[4:6], s[6:8], s[9:11], s[12:14], s[15:17]))
3.530 @@ -473,6 +676,13 @@
3.531 "base64" : str
3.532 }
3.533
3.534 +typenames = {
3.535 + "str" : "string",
3.536 + "int" : "int",
3.537 + "bool" : "boolean",
3.538 + "float" : "double"
3.539 + }
3.540 +
3.541 # Implementation-related functionality.
3.542
3.543 class XMLRPCImplementation(libxml2dom.Implementation):
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/tests/test_xmlrpc_parse.py Sun Sep 14 02:30:58 2008 +0200
5.3 @@ -0,0 +1,192 @@
5.4 +#!/usr/bin/env python
5.5 +
5.6 +import libxml2dom.xmlrpc
5.7 +
5.8 +# Some examples from the specification.
5.9 +
5.10 +request = """<?xml version="1.0"?>
5.11 +<methodCall>
5.12 + <methodName>examples.getStateName</methodName>
5.13 + <params>
5.14 + <param>
5.15 + <value><i4>41</i4></value>
5.16 + </param>
5.17 + </params>
5.18 +</methodCall>"""
5.19 +
5.20 +req = libxml2dom.xmlrpc.parseString(request)
5.21 +print "Method name:", req.method.methodName
5.22 +print "Parameter values:", req.method.parameterValues
5.23 +print "Fault:", req.fault
5.24 +assert req.method.methodName == "examples.getStateName"
5.25 +assert req.method.parameterValues == [41]
5.26 +assert req.method.parameters[0].valueElement.container == 41
5.27 +assert req.method.params.values()[0] == 41
5.28 +assert req.fault is None
5.29 +
5.30 +response = """<?xml version="1.0"?>
5.31 +<methodResponse>
5.32 + <params>
5.33 + <param>
5.34 + <value><string>South Dakota</string></value>
5.35 + </param>
5.36 + </params>
5.37 +</methodResponse>"""
5.38 +
5.39 +resp = libxml2dom.xmlrpc.parseString(response)
5.40 +print "Method name:", resp.method.methodName
5.41 +print "Parameter values:", resp.method.parameterValues
5.42 +print "Fault:", resp.fault
5.43 +assert resp.method.methodName is None
5.44 +assert resp.method.parameterValues == ["South Dakota"]
5.45 +assert resp.fault is None
5.46 +
5.47 +failed = """<?xml version="1.0"?>
5.48 +<methodResponse>
5.49 + <fault>
5.50 + <value>
5.51 + <struct>
5.52 + <member>
5.53 + <name>faultCode</name>
5.54 + <value><int>4</int></value>
5.55 + </member>
5.56 + <member>
5.57 + <name>faultString</name>
5.58 + <value><string>Too many parameters.</string></value>
5.59 + </member>
5.60 + </struct>
5.61 + </value>
5.62 + </fault>
5.63 +</methodResponse>"""
5.64 +
5.65 +f = libxml2dom.xmlrpc.parseString(failed)
5.66 +print "Method name:", f.method.methodName
5.67 +print "Parameter values:", f.method.parameterValues
5.68 +print "Fault code:", f.fault.code
5.69 +assert f.method.methodName is None
5.70 +assert f.method.parameterValues is None
5.71 +assert f.fault.code == "4"
5.72 +assert f.fault.reason == "Too many parameters."
5.73 +
5.74 +# Python Package Index examples.
5.75 +
5.76 +search = """<?xml version="1.0"?>
5.77 +<methodCall>
5.78 + <methodName>search</methodName>
5.79 + <params>
5.80 + <param>
5.81 + <value>
5.82 + <struct>
5.83 + <member>
5.84 + <name>name</name>
5.85 + <value><string>libxml2dom</string></value>
5.86 + </member>
5.87 + <member>
5.88 + <name>description</name>
5.89 + <value>XML</value>
5.90 + </member>
5.91 + </struct>
5.92 + </value>
5.93 + </param>
5.94 + <param>
5.95 + <value>
5.96 + <string>and</string>
5.97 + </value>
5.98 + </param>
5.99 + </params>
5.100 +</methodCall>"""
5.101 +
5.102 +s = libxml2dom.xmlrpc.parseString(search)
5.103 +print "Method name:", s.method.methodName
5.104 +print "Parameter values:", s.method.parameterValues
5.105 +print "Fault:", s.fault
5.106 +assert s.method.methodName == "search"
5.107 +assert s.method.parameterValues == [
5.108 + [
5.109 + ("name", "libxml2dom"),
5.110 + ("description", "XML")
5.111 + ],
5.112 + "and"
5.113 + ]
5.114 +assert s.fault is None
5.115 +
5.116 +# Nested structure examples.
5.117 +
5.118 +search2 = """<?xml version="1.0"?>
5.119 +<methodCall>
5.120 + <methodName>search</methodName>
5.121 + <params>
5.122 + <param>
5.123 + <value>
5.124 + <struct>
5.125 + <member>
5.126 + <name>names</name>
5.127 + <value>
5.128 + <struct>
5.129 + <member>
5.130 + <name>name</name>
5.131 + <value><string>libxml2dom</string></value>
5.132 + </member>
5.133 + <member>
5.134 + <name>description</name>
5.135 + <value>XML</value>
5.136 + </member>
5.137 + </struct>
5.138 + </value>
5.139 + </member>
5.140 + </struct>
5.141 + </value>
5.142 + </param>
5.143 + <param>
5.144 + <value>
5.145 + <string>and</string>
5.146 + </value>
5.147 + </param>
5.148 + </params>
5.149 +</methodCall>"""
5.150 +
5.151 +s2 = libxml2dom.xmlrpc.parseString(search2)
5.152 +print "Method name:", s2.method.methodName
5.153 +print "Parameter values:", s2.method.parameterValues
5.154 +print "Fault:", s2.fault
5.155 +assert s2.method.methodName == "search"
5.156 +assert s2.method.parameterValues == [
5.157 + [
5.158 + ("names", [
5.159 + ("name", "libxml2dom"),
5.160 + ("description", "XML")
5.161 + ])
5.162 + ],
5.163 + "and"
5.164 + ]
5.165 +assert s2.fault is None
5.166 +
5.167 +arrays = """<?xml version="1.0"?>
5.168 +<methodResponse>
5.169 + <params>
5.170 + <param>
5.171 + <value>
5.172 + <array>
5.173 + <data>
5.174 + <value>
5.175 + <string>libxml2dom</string>
5.176 + </value>
5.177 + <value>
5.178 + <string>XSLTools</string>
5.179 + </value>
5.180 + </data>
5.181 + </array>
5.182 + </value>
5.183 + </param>
5.184 + </params>
5.185 +</methodResponse>"""
5.186 +
5.187 +a = libxml2dom.xmlrpc.parseString(arrays)
5.188 +print "Method name:", a.method.methodName
5.189 +print "Parameter values:", a.method.parameterValues
5.190 +print "Fault:", a.fault
5.191 +assert a.method.methodName is None
5.192 +assert a.method.parameterValues == [["libxml2dom", "XSLTools"]]
5.193 +assert a.fault is None
5.194 +
5.195 +# vim: tabstop=4 expandtab shiftwidth=4
6.1 --- a/tests/xmlrpc_test.py Fri Sep 12 01:03:56 2008 +0200
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,190 +0,0 @@
6.4 -#!/usr/bin/env python
6.5 -
6.6 -import libxml2dom.xmlrpc
6.7 -
6.8 -# Some examples from the specification.
6.9 -
6.10 -request = """<?xml version="1.0"?>
6.11 -<methodCall>
6.12 - <methodName>examples.getStateName</methodName>
6.13 - <params>
6.14 - <param>
6.15 - <value><i4>41</i4></value>
6.16 - </param>
6.17 - </params>
6.18 - </methodCall>"""
6.19 -
6.20 -req = libxml2dom.xmlrpc.parseString(request)
6.21 -assert req.method.methodName == "examples.getStateName"
6.22 -assert req.method.parameterValues == [41]
6.23 -assert req.fault is None
6.24 -print "Method name:", req.method.methodName
6.25 -print "Parameter values:", req.method.parameterValues
6.26 -print "Fault:", req.fault
6.27 -
6.28 -response = """<?xml version="1.0"?>
6.29 -<methodResponse>
6.30 - <params>
6.31 - <param>
6.32 - <value><string>South Dakota</string></value>
6.33 - </param>
6.34 - </params>
6.35 - </methodResponse>"""
6.36 -
6.37 -resp = libxml2dom.xmlrpc.parseString(response)
6.38 -assert resp.method.methodName is None
6.39 -assert resp.method.parameterValues == ["South Dakota"]
6.40 -assert resp.fault is None
6.41 -print "Method name:", resp.method.methodName
6.42 -print "Parameter values:", resp.method.parameterValues
6.43 -print "Fault:", resp.fault
6.44 -
6.45 -failed = """<?xml version="1.0"?>
6.46 -<methodResponse>
6.47 - <fault>
6.48 - <value>
6.49 - <struct>
6.50 - <member>
6.51 - <name>faultCode</name>
6.52 - <value><int>4</int></value>
6.53 - </member>
6.54 - <member>
6.55 - <name>faultString</name>
6.56 - <value><string>Too many parameters.</string></value>
6.57 - </member>
6.58 - </struct>
6.59 - </value>
6.60 - </fault>
6.61 - </methodResponse>"""
6.62 -
6.63 -f = libxml2dom.xmlrpc.parseString(failed)
6.64 -assert f.method.methodName is None
6.65 -assert f.method.parameterValues == []
6.66 -assert f.fault.code == "4"
6.67 -assert f.fault.reason == "Too many parameters."
6.68 -print "Method name:", f.method.methodName
6.69 -print "Parameter values:", f.method.parameterValues
6.70 -print "Fault code:", f.fault.code
6.71 -
6.72 -# Python Package Index examples.
6.73 -
6.74 -search = """<?xml version="1.0"?>
6.75 -<methodCall>
6.76 - <methodName>search</methodName>
6.77 - <params>
6.78 - <param>
6.79 - <value>
6.80 - <struct>
6.81 - <member>
6.82 - <name>name</name>
6.83 - <value><string>libxml2dom</string></value>
6.84 - </member>
6.85 - <member>
6.86 - <name>description</name>
6.87 - <value>XML</value>
6.88 - </member>
6.89 - </struct>
6.90 - </value>
6.91 - </param>
6.92 - <param>
6.93 - <value>
6.94 - <string>and</string>
6.95 - </value>
6.96 - </param>
6.97 - </params>
6.98 -</methodCall>"""
6.99 -
6.100 -s = libxml2dom.xmlrpc.parseString(search)
6.101 -assert s.method.methodName == "search"
6.102 -assert s.method.parameterValues == [
6.103 - [
6.104 - ("name", "libxml2dom"),
6.105 - ("description", "XML")
6.106 - ],
6.107 - "and"
6.108 - ]
6.109 -assert s.fault is None
6.110 -print "Method name:", s.method.methodName
6.111 -print "Parameter values:", s.method.parameterValues
6.112 -print "Fault:", s.fault
6.113 -
6.114 -# Nested structure examples.
6.115 -
6.116 -search2 = """<?xml version="1.0"?>
6.117 -<methodCall>
6.118 - <methodName>search</methodName>
6.119 - <params>
6.120 - <param>
6.121 - <value>
6.122 - <struct>
6.123 - <member>
6.124 - <name>names</name>
6.125 - <value>
6.126 - <struct>
6.127 - <member>
6.128 - <name>name</name>
6.129 - <value><string>libxml2dom</string></value>
6.130 - </member>
6.131 - <member>
6.132 - <name>description</name>
6.133 - <value>XML</value>
6.134 - </member>
6.135 - </struct>
6.136 - </value>
6.137 - </member>
6.138 - </struct>
6.139 - </value>
6.140 - </param>
6.141 - <param>
6.142 - <value>
6.143 - <string>and</string>
6.144 - </value>
6.145 - </param>
6.146 - </params>
6.147 -</methodCall>"""
6.148 -
6.149 -s2 = libxml2dom.xmlrpc.parseString(search2)
6.150 -assert s2.method.methodName == "search"
6.151 -assert s2.method.parameterValues == [
6.152 - [
6.153 - ("names", [
6.154 - ("name", "libxml2dom"),
6.155 - ("description", "XML")
6.156 - ])
6.157 - ],
6.158 - "and"
6.159 - ]
6.160 -assert s2.fault is None
6.161 -print "Method name:", s2.method.methodName
6.162 -print "Parameter values:", s2.method.parameterValues
6.163 -print "Fault:", s2.fault
6.164 -
6.165 -arrays = """<?xml version="1.0"?>
6.166 - <methodResponse>
6.167 - <params>
6.168 - <param>
6.169 - <value>
6.170 - <array>
6.171 - <data>
6.172 - <value>
6.173 - <string>libxml2dom</string>
6.174 - </value>
6.175 - <value>
6.176 - <string>XSLTools</string>
6.177 - </value>
6.178 - </data>
6.179 - </array>
6.180 - </value>
6.181 - </param>
6.182 - </params>
6.183 - </methodResponse>"""
6.184 -
6.185 -a = libxml2dom.xmlrpc.parseString(arrays)
6.186 -assert a.method.methodName is None
6.187 -assert a.method.parameterValues == [["libxml2dom", "XSLTools"]]
6.188 -assert a.fault is None
6.189 -print "Method name:", a.method.methodName
6.190 -print "Parameter values:", a.method.parameterValues
6.191 -print "Fault:", a.fault
6.192 -
6.193 -# vim: tabstop=4 expandtab shiftwidth=4