|
From: <bov...@us...> - 2006-10-13 23:35:33
|
Revision: 1266
http://svn.sourceforge.net/pywebsvcs/?rev=1266&view=rev
Author: boverhof
Date: 2006-10-13 16:35:29 -0700 (Fri, 13 Oct 2006)
Log Message:
-----------
M test/test_t8.py
M ZSI/TCnumbers.py
M ZSI/TC.py
M ZSI/TCcompound.py
M doc/c06-tc.tex
-- added some of the examples to unittest code
-- some cleanup in code, remove outdated stuff, comments, use booleans.
-- updates to Typecode chapter
Modified Paths:
--------------
trunk/zsi/ZSI/TC.py
trunk/zsi/ZSI/TCcompound.py
trunk/zsi/ZSI/TCnumbers.py
trunk/zsi/doc/c06-tc.tex
trunk/zsi/test/test_t8.py
Modified: trunk/zsi/ZSI/TC.py
===================================================================
--- trunk/zsi/ZSI/TC.py 2006-10-13 00:12:32 UTC (rev 1265)
+++ trunk/zsi/ZSI/TC.py 2006-10-13 23:35:29 UTC (rev 1266)
@@ -842,7 +842,7 @@
type = (SCHEMA.XSD3, 'string')
logger = _GetLogger('ZSI.TC.String')
- def __init__(self, pname=None, strip=1, **kw):
+ def __init__(self, pname=None, strip=True, **kw):
TypeCode.__init__(self, pname, **kw)
if kw.has_key('resolver'): self.resolver = kw['resolver']
self.strip = strip
@@ -852,7 +852,7 @@
'''
if self.strip: text = text.strip()
if self.pyclass is not None:
- return self.pyclass(text)
+ return self.pyclass(text)
return text
def get_formatted_content(self, pyobj):
@@ -1047,7 +1047,14 @@
ps.Backtrace(elt))
return val
+ def serialize(self, elt, sw, pyobj, name=None, orig=None, **kw):
+ if pyobj not in self.choices:
+ raise EvaluateException('Value not in enumeration list',
+ ps.Backtrace(elt))
+ String.serialize(self, elt, sw, pyobj, name=name, orig=orig, **kw)
+
+
# This is outside the Integer class purely for code esthetics.
_ignored = []
Modified: trunk/zsi/ZSI/TCcompound.py
===================================================================
--- trunk/zsi/ZSI/TCcompound.py 2006-10-13 00:12:32 UTC (rev 1265)
+++ trunk/zsi/ZSI/TCcompound.py 2006-10-13 23:35:29 UTC (rev 1266)
@@ -96,10 +96,9 @@
logger = _GetLogger('ZSI.TCcompound.ComplexType')
def __init__(self, pyclass, ofwhat, pname=None, inorder=False, inline=False,
- mutable=True, hasextras=0, mixed=False, mixed_aname='_text', **kw):
+ mutable=True, mixed=False, mixed_aname='_text', **kw):
'''pyclass -- the Python class to hold the fields
ofwhat -- a list of fields to be in the complexType
- hasextras -- ignore extra input fields
inorder -- fields must be in exact order or not
inline -- don't href/id when serializing
mutable -- object could change between multiple serializations
@@ -117,7 +116,6 @@
self.mixed_aname = mixed_aname
if self.mutable is True: self.inline = True
- self.hasextras = hasextras
self.type = kw.get('type') or _get_xsitype(self)
t = type(ofwhat)
if t not in _seqtypes:
@@ -158,16 +156,6 @@
c = _child_elements(elt)
count = len(c)
if self.nilled(elt, ps): return Nilled
-# repeatable_args = False
-# for tc in self.ofwhat:
-# if tc.maxOccurs > 1:
-# repeatable_args = True
-# break
-#
-# if not repeatable_args:
-# if count > len(self.ofwhat) and not self.hasextras:
-# raise EvaluateException('Too many sub-elements (%d>%d)' %(
-# count,len(self.ofwhat)), ps.Backtrace(elt))
# Create the object.
v = {}
@@ -268,11 +256,7 @@
# type definition must be informed of element tag (nspname,pname),
# element declaration is initialized with a tag.
try:
- if issubclass(self.pyclass, ElementDeclaration) is False and\
- issubclass(self.pyclass, TypeDefinition) is True:
- pyobj = self.pyclass((self.nspname,self.pname))
- else:
- pyobj = self.pyclass()
+ pyobj = self.pyclass()
except Exception, e:
raise TypeError("Constructing element (%s,%s) with pyclass(%s), %s" \
%(self.nspname, self.pname, self.pyclass.__name__, str(e)))
@@ -469,7 +453,7 @@
class Struct(ComplexType):
'''Struct is a complex type for accessors identified by name.
- Constraint: No element may be have the same name as any other,
+ Constraint: No element may have the same name as any other,
nor may any element have a maxOccurs > 1.
<xs:group name="Struct" >
@@ -486,17 +470,16 @@
logger = _GetLogger('ZSI.TCcompound.Struct')
def __init__(self, pyclass, ofwhat, pname=None, inorder=False, inline=False,
- mutable=True, hasextras=0, **kw):
+ mutable=True, **kw):
'''pyclass -- the Python class to hold the fields
ofwhat -- a list of fields to be in the struct
- hasextras -- ignore extra input fields
inorder -- fields must be in exact order or not
inline -- don't href/id when serializing
mutable -- object could change between multiple serializations
'''
ComplexType.__init__(self, pyclass, ofwhat, pname=pname,
inorder=inorder, inline=inline, mutable=mutable,
- hasextras=hasextras, **kw
+ **kw
)
# Check Constraints
@@ -533,7 +516,7 @@
raise TypeError("Only single-dimensioned arrays supported")
self.fill = fill
self.sparse = sparse
- if self.sparse: ofwhat.optional = 1
+ #if self.sparse: ofwhat.minOccurs = 0
self.mutable = mutable
self.size = size
self.nooffset = nooffset
Modified: trunk/zsi/ZSI/TCnumbers.py
===================================================================
--- trunk/zsi/ZSI/TCnumbers.py 2006-10-13 00:12:32 UTC (rev 1265)
+++ trunk/zsi/ZSI/TCnumbers.py 2006-10-13 23:35:29 UTC (rev 1266)
@@ -126,6 +126,13 @@
ps.Backtrace(elt))
return val
+ def serialize(self, elt, sw, pyobj, name=None, orig=None, **kw):
+ if pyobj not in self.choices:
+ raise EvaluateException('Value not in int enumeration list',
+ ps.Backtrace(elt))
+ Integer.serialize(self, elt, sw, pyobj, name=name, orig=orig, **kw)
+
+
class FPfloat(Decimal):
'''IEEE 32bit floating point value.
'''
@@ -166,5 +173,12 @@
'" not in enumeration list',
ps.Backtrace(elt))
return val
+
+ def serialize(self, elt, sw, pyobj, name=None, orig=None, **kw):
+ if pyobj not in self.choices:
+ raise EvaluateException('Value not in int enumeration list',
+ ps.Backtrace(elt))
+ Decimal.serialize(self, elt, sw, pyobj, name=name, orig=orig, **kw)
+
if __name__ == '__main__': print _copyright
Modified: trunk/zsi/doc/c06-tc.tex
===================================================================
--- trunk/zsi/doc/c06-tc.tex 2006-10-13 00:12:32 UTC (rev 1265)
+++ trunk/zsi/doc/c06-tc.tex 2006-10-13 23:35:29 UTC (rev 1266)
@@ -35,9 +35,11 @@
The \code{nsdict} parameter to the \class{SoapWriter} construct can be used to
specify prefix to namespace-URI mappings, these are otherwise handled automatically.
+\section{\class{TC.TypeCode}}
+
+The \class{TypeCode} class is the parent class of all typecodes.
+
\begin{classdesc}{TypeCode}{**keywords}
-The \code{pname}
-
The following keyword arguments may be used:
\begin{tableiii}{l|c|p{30em}}{textrm}{Keyword}{Default}{Description}
@@ -150,7 +152,8 @@
for the fourth.
\subsection{compound data} -- Struct or Array
-Compound data, such as a \code{struct}, may also be self-describing:
+Compound data, such as a \code{struct}, may also be self-describing (namespace
+are omitted for clarity):
\begin{verbatim}
<tns:foo>
<tns:i xsi:type="SOAP-ENC:integer">12</tns:i>
@@ -161,8 +164,11 @@
If this is parsed with a \class{TC.Any} typecode, either a Python \code{dict}
is created or if \code{aslist} is True a \code{list}:
\begin{verbatim}
+ps = ParsedSoap(xml, envelope=False)
+print ps.Parse(TC.Any())
{ 'name': u'Hello world', 'i': 12 }
+print ps.Parse(TC.Any(aslist=True))
[ 12, u'Hello world' ]
\end{verbatim}
Note that one preserves order, while the other preserves the element names.
@@ -193,8 +199,18 @@
This class would know that the \code{i} element is an integer,
so that the explicit typing becomes optional, rather than required.
-The rest of this section describes how to add new
-types to the \ZSI{} typecode engine.
+\subsection{Adding new types} Most of the \class{TypeCodes} classes in
+\module{TC} are registered with \class{Any}, making an instance of itself
+available for dynamic typing. New \class{TypeCode} classes can be created and
+registered with \class{Any} by using \function{RegisterType}. In order to
+override an existing entry in the registry call \function{RegisterType} with
+\code{clobber=True}. The serialization entries are mappings between builtin
+Python types and a \class{TypeCode} instance, it is not possible to have one
+Python type map to multiple typecodes. The parsing entries are mappings
+between \code{(namespaceURI,name)} tuples, representing the \code{xsi:type}
+attribute, and a \class{TypeCode} instance. Thus, only one instance of a
+\class{TypeCode} class can represent a XML Schema type. So this mechanism is
+not appropriate for representing XML Schema element information.
\begin{classdesc}{\emph{NEWTYPECODE}(TypeCode)}{...}
The new typecode should be derived from the \class{TC.TypeCode} class, and
@@ -272,15 +288,21 @@
processed as dynamic types.
This may be acceptable in some environments.
+\section{\class{TC.SimpleType}}
+Parent class of all simple types.
+
+\begin{memberdesc}{empty_content}
+This is a class attribute.
+Value returned when tag or node is present, is not nilled, and without text
+content.
+\end{memberdesc}
+
\section{Strings}
-SOAP Strings are Python strings.
-If the value to be serialized is a Python sequence, then an \code{href}
-is generated, with the first element of the sequence used as the URI.
-This can be used, for example, when generating SOAP with attachments.
+SOAP/XMLSchema Strings are Python strings.
\begin{classdesc}{String}{name\optional{, **keywords}}
-The parent type of all SOAP strings.
+The parent type of all strings.
The following keyword arguments may be used:
@@ -288,17 +310,14 @@
\lineiii{\code{resolver}}{\code{None}}{A function that can resolve an
absolute URI and return its content as a string, as described in the
\class{ParsedSoap} description.}
-\lineiii{\code{strip}}{\code{1}}{If true, leading and trailing whitespace
+\lineiii{\code{strip}}{\code{True}}{If true, leading and trailing whitespace
are stripped from the content.}
-\lineiii{\code{textprotect}}{\code{1}}{If true, less-than and ampersand
-characters are replaced with \code{\<} and \code{\&}, respectively.
-\versionadded{1.1}}
\end{tableiii}
\end{classdesc}
\begin{classdesc}{Enumeration}{value_list, name\optional{, **keywords}}
Like \class{TC.String}, but the value must be a member of
-the \code{value_list} sequence of text strings
+the \code{choices} sequence of text strings
\end{classdesc}
In addition to \class{TC.String},
@@ -374,9 +393,9 @@
\section{Integers}
-SOAP integers are Python integers.
+SOAP/XMLSchema integers are Python integers.
-\begin{classdesc}{Integer}{name\optional{, **keywords}}
+\begin{classdesc}{Integer}{\optional{**keywords}}
The parent type of all integers.
This class handles any of the several types (and ranges) of SOAP integers.
@@ -388,66 +407,66 @@
\end{tableiii}
\end{classdesc}
-\begin{classdesc}{IEnumeration}{value_list, name\optional{, **keywords}}
+\begin{classdesc}{IEnumeration}{choices\optional{, **keywords}}
Like \class{TC.Integer}, but the value must be a member of
-the \code{value_list} sequence.
+the \code{choices} sequence.
\end{classdesc}
A number of sub-classes are defined to handle smaller-ranged numbers.
-\begin{classdesc}{Ibyte}{name\optional{, **keywords}}
+\begin{classdesc}{Ibyte}{\optional{**keywords}}
A signed eight-bit value.
\end{classdesc}
-\begin{classdesc}{IunsignedByte}{name\optional{, **keywords}}
+\begin{classdesc}{IunsignedByte}{\optional{**keywords}}
An unsigned eight-bit value.
\end{classdesc}
-\begin{classdesc}{Ishort}{name\optional{, **keywords}}
+\begin{classdesc}{Ishort}{\optional{**keywords}}
A signed 16-bit value.
\end{classdesc}
-\begin{classdesc}{IunsignedShort}{name\optional{, **keywords}}
+\begin{classdesc}{IunsignedShort}{\optional{**keywords}}
An unsigned 16-bit value.
\end{classdesc}
-\begin{classdesc}{Iint}{name\optional{, **keywords}}
+\begin{classdesc}{Iint}{\optional{**keywords}}
A signed 32-bit value.
\end{classdesc}
-\begin{classdesc}{IunsignedInt}{name\optional{, **keywords}}
+\begin{classdesc}{IunsignedInt}{\optional{**keywords}}
An unsigned 32-bit value.
\end{classdesc}
-\begin{classdesc}{Ilong}{name\optional{, **keywords}}
+\begin{classdesc}{Ilong}{\optional{**keywords}}
An signed 64-bit value.
\end{classdesc}
-\begin{classdesc}{IunsignedLong}{name\optional{, **keywords}}
+\begin{classdesc}{IunsignedLong}{\optional{**keywords}}
An unsigned 64-bit value.
\end{classdesc}
-\begin{classdesc}{IpositiveInteger}{name\optional{, **keywords}}
+\begin{classdesc}{IpositiveInteger}{\optional{**keywords}}
A value greater than zero.
\end{classdesc}
-\begin{classdesc}{InegativeInteger}{name\optional{, **keywords}}
+\begin{classdesc}{InegativeInteger}{\optional{**keywords}}
A value less than zero.
\end{classdesc}
-\begin{classdesc}{InonPositiveInteger}{name\optional{, **keywords}}
+\begin{classdesc}{InonPositiveInteger}{\optional{**keywords}}
A value less than or equal to zero.
\end{classdesc}
-\begin{classdesc}{InonNegativeInteger}{name\optional{, **keywords}}
+\begin{classdesc}{InonNegativeInteger}{\optional{**keywords}}
A value greater than or equal to zero.
\end{classdesc}
\section{Floating-point Numbers}
-SOAP floating point numbers are Python floats.
+SOAP/XMLSchema floating point numbers are Python floats.
-\begin{classdesc}{Decimal}{name\optional{, **keywords}}
+\begin{classdesc}{Decimal}{\optional{**keywords}}
The parent type of all floating point numbers.
This class handles any of the several types (and ranges) of SOAP
floating point numbers.
@@ -515,43 +534,43 @@
When serializing, an integral or floating point number is taken as
the number of seconds since the epoch, in UTC.
-\begin{classdesc}{Duration}{name\optional{, **keywords}}
+\begin{classdesc}{Duration}{\optional{**keywords}}
A relative time period.
Negative durations have all values less than zero; this makes
it easy to add a duration to a Python time tuple.
\end{classdesc}
-\begin{classdesc}{Gregorian}{name\optional{, **keywords}}
+\begin{classdesc}{Gregorian}{\optional{**keywords}}
An absolute time period.
This class should not be instantiated directly; use one of the \code{gXXX}
classes instead.
\end{classdesc}
-\begin{classdesc}{gDateTime}{name\optional{, **keywords}}
+\begin{classdesc}{gDateTime}{\optional{**keywords}}
A date and time.
\end{classdesc}
-\begin{classdesc}{gDate}{name\optional{, **keywords}}
+\begin{classdesc}{gDate}{\optional{**keywords}}
A date.
\end{classdesc}
-\begin{classdesc}{gYearMonth}{name\optional{, **keywords}}
+\begin{classdesc}{gYearMonth}{\optional{**keywords}}
A year and month.
\end{classdesc}
-\begin{classdesc}{gYear}{name\optional{, **keywords}}
+\begin{classdesc}{gYear}{\optional{**keywords}}
A year.
\end{classdesc}
-\begin{classdesc}{gMonthDay}{name\optional{, **keywords}}
+\begin{classdesc}{gMonthDay}{\optional{**keywords}}
A month and day.
\end{classdesc}
-\begin{classdesc}{gDay}{name\optional{, **keywords}}
+\begin{classdesc}{gDay}{\optional{**keywords}}
A day.
\end{classdesc}
-\begin{classdesc}{gTime}{name\optional{, **keywords}}
+\begin{classdesc}{gTime}{\optional{**keywords}}
A time.
\end{classdesc}
@@ -559,7 +578,7 @@
SOAP Booleans are Python integers.
-\begin{classdesc}{Boolean}{name\optional{, **keywords}}
+\begin{classdesc}{Boolean}{\optional{**keywords}}
When marshaling zero or the word ``false'' is returned as \code{0}
and any non-zero value or the word ``true'' is returned as \code{1}.
When serializing, the number \code{0} or \code{1} will be generated.
@@ -583,7 +602,7 @@
Note that it is generally more efficient to keep the \class{ParsedSoap}
object alive until the XML data is no longerneeded.
-\begin{classdesc}{XML}{name\optional{, **keywords}}
+\begin{classdesc}{XML}{\optional{**keywords}}
This typecode represents a portion of an XML document embedded in a SOAP
message.
The value is the element node.
@@ -616,37 +635,31 @@
identifying the namespace prefixes that should be output.}
\end{tableiii}
-\section{Struct}
+\section{ComplexType}
-SOAP structs are either Python dictionaries or
-instances of application-specified classes.
+Represents the XMLSchema ComplexType .
+\versionadded{2.0}
-\begin{classdesc}{Struct}{pyclass, typecode_seq, name\optional{, **keywords}}
+\begin{classdesc}{ComplexType}{pyclass, ofwhat\optional{, **keywords}}
This class defines a compound data structure.
If \code{pyclass} is \code{None}, then the data will be marshaled
-into a Python dictionary, and each item in the \code{typecode_seq} sequence
+into a Python dictionary, and each item in the \code{ofwhat} sequence
specifies a (possible) dictionary entry.
-Otherwise, \code{pyclass} must be a Python class object whose constructor
-takes a single parameter, which will be the value of the \code{name}
-parameter given in the \class{TC.Struct} constructor.
-(This allows a single \code{pyclass} to be used for different typecodes.)
+Otherwise, \code{pyclass} must be a Python class object.
The data is then marshaled into the object, and each item in the
-\code{typecode_seq}
+\code{ofwhat}
sequence specifies an attribute of the instance to set.
-Note that each typecode in \code{typecode_seq} must have a name.
+Note that each typecode in \code{ofwhat} must have a name.
The following keyword arguments may be used:
\begin{tableiii}{l|c|p{30em}}{textrm}{Keyword}{Default}{Description}
-\lineiii{\code{hasextras}}{\code{0}}{Ignore any extra elements that appear
-in the in the structure.
-If \code{inorder} is true, extras can only appear at the end.}
-\lineiii{\code{inorder}}{\code{0}}{Items within the structure must appear
-in the order specified in the \code{TCseq} sequence.}
-\lineiii{\code{inline}}{\code{0}}{The structure is single-reference,
+\lineiii{\code{inorder}}{\code{False}}{Items within the structure must appear
+in the order specified in the \code{ofwhat} sequence.}
+\lineiii{\code{inline}}{\code{False}}{The structure is single-reference,
so ZSI does not have to use \code{href/id} encodings.}
-\lineiii{\code{mutable}}{\code{0}}{If an object is going to be serialized
+\lineiii{\code{mutable}}{\code{False}}{If an object is going to be serialized
multiple times, and its state may be modified between serializations,
then this keyword should be used, otherwise a single instance will be
serialized, with multiple references to it.
@@ -659,11 +672,15 @@
specified by this parameter.
By default, type-checking is not done for structures; matching child element
names is usually sufficient and senders rarely provide type information.}
+\lineiii{\code{mixed}}{\code{False}}{using a mixed content model, allow text and
+element content.}
+\lineiii{\code{mixed_aname}}{\code{'_text'}}{if mixed is True, text
+content is set in this attribute (key).}
\end{tableiii}
If the \code{typed} keyword is used, then its value is assigned to
-all typecodes in the \code{typecode_seq} parameter.
-If any of the typecodes in \code{typecode_seq} are repeatable, then the
+all typecodes in the \code{ofwhat} parameter.
+If any of the typecodes in \code{ofwhat} are repeatable, then the
\code{inorder} keyword should not be used and the \code{hasextras} parameter
\emph{must} be used.
@@ -688,25 +705,12 @@
\end{verbatim}
\end{classdesc}
-\section{Choice}
+\section{Struct}
-A choice is a Python two-element \samp{(name, value)} tuple, representing
-a union of different types.
-The first item is a string identifying the type, and the second is the
-actual data.
+SOAP Struct is a complex type for accessors identified by name. No element may
+have the same name as any other, nor may any element have a maxOccurs > 1.
+SOAP Structs are either Python dictionaries or instances of application-specified classes.
-\begin{classdesc}{Choice}{typecode_seq, name\optional{, **keywords}}
-When parsing, ZSI will look at the element name in the SOAP message, and
-determine which of the choices to create.
-
-When serializing Python objects to SOAP messages, \ZSI{} must be
-explicitly told which of the choices define the data.
-This is done by passing a two-element tuple.
-The first item is a string identifying the name of a typecode
-from the \code{typecode_seq} list of typecodes.
-The second is the object to be serialized.
-\end{classdesc}
-
\section{Arrays}
SOAP arrays are Python lists; multi-dimensional arrays are
@@ -718,9 +722,9 @@
\strong{Currently only singly-dimensioned arrays are supported.}
-\begin{classdesc}{Array}{atype, ofwhat, name\optional{, **keywords}}
-The \code{atype} parameter is a text string representing the SOAP array type.
-the \code{ofwhat} parameter is a typecode describing the array elements.
+\begin{classdesc}{Array}{atype, ofwhat\optional{, **keywords}}
+The \code{atype} parameter is a \code{(URI,NCName)} tuple representing the SOAP
+array type. The \code{ofwhat} parameter is a typecode describing the array elements.
\end{classdesc}
The following keyword arguments may be used:
@@ -732,14 +736,16 @@
the array.}
\lineiii{\code{fill}}{\code{None}}{The value to use when an array
element is omitted.}
-\lineiii{\code{mutable}}{\code{0}}{Same as \class{TC.Struct}
-\versionadded{1.2}}
+\lineiii{\code{mutable}}{\code{False}}{If an object is going to be serialized
+multiple times, and its state may be modified between serializations,
+then this keyword should be used, otherwise a single instance will be
+serialized, with multiple references to it.}
\lineiii{\code{nooffset}}{\code{0}}{Do not use the SOAP \code{offset}
attribute so skip leading elements with the same value as \code{fill}.}
-\lineiii{\code{sparse}}{\code{0}}{The array is sparse.}
+\lineiii{\code{sparse}}{\code{False}}{The array is sparse.}
\lineiii{\code{size}}{\code{None}}{An integer or list of integers that
specifies the maximum array dimensions.}
-\lineiii{\code{undeclared}}{\code{0}}{The SOAP \samp{arrayType} attribute
+\lineiii{\code{undeclared}}{\code{False}}{The SOAP \samp{arrayType} attribute
need not appear.}
\end{tableiii}
Modified: trunk/zsi/test/test_t8.py
===================================================================
--- trunk/zsi/test/test_t8.py 2006-10-13 00:12:32 UTC (rev 1265)
+++ trunk/zsi/test/test_t8.py 2006-10-13 23:35:29 UTC (rev 1266)
@@ -1,9 +1,15 @@
#!/usr/bin/env python
import unittest, sys
from ZSI import *
+from ZSI.wstools.Namespaces import SCHEMA, SOAP
+NSDICT = {'tns':'xmlns:tns="urn:a"',
+ 'xsi':'xmlns:xsi="%s"' %SCHEMA.XSI3,
+ 'xsd':'xmlns:xsd="%s"' %SCHEMA.XSD3,
+ 'soap':'xmlns:SOAP-ENC="%s"' %SOAP.ENC,
+}
-class t8TestCase(unittest.TestCase):
+class AnyTestCase(unittest.TestCase):
"Test Any serialize and parse"
def check_parse_empty_all(self):
@@ -26,8 +32,6 @@
sw = SoapWriter()
sw.serialize("", typecode=tc, typed=True)
soap = str(sw)
- print
- print soap
ps = ParsedSoap(soap)
parsed = ps.Parse(Any())
self.assertEqual("", parsed)
@@ -39,7 +43,6 @@
sw = SoapWriter()
sw.serialize(orig, typecode=Any(pname="builtins", aslist=True))
- print >>sys.stdout, sw
ps = ParsedSoap(str(sw))
parsed = ps.Parse(Any())
@@ -57,26 +60,87 @@
self.assertEqual(tuple, type(parsed[3]))
self.assertEqual(type(myFloat), type(parsed[4]))
-
- def check_Any_nill(self):
+ def check_any_nill(self):
result = ['23', {'a' : None, 'b': 5}]
soap = str(SoapWriter().serialize(result, TC.Any(pname="NilRequest", nillable=True, aslist=True)))
- print soap
ps = ParsedSoap(soap)
tc = TC.Any(nillable=True)
pyobj = ps.Parse(tc)
+ def check_any_compound(self):
+ # from zsi developer's guide
+ xml = """
+<tns:foo %(tns)s %(xsi)s %(soap)s>
+ <tns:i xsi:type="SOAP-ENC:integer">12</tns:i>
+ <tns:name xsi:type="SOAP-ENC:string">Hello world</tns:name>
+</tns:foo>""" %NSDICT
-def makeTestSuite():
- suite = unittest.TestSuite()
- suite.addTest(unittest.makeSuite(t8TestCase, "check"))
- return suite
+ ps = ParsedSoap(xml, envelope=False)
+ self.failUnless(ps.Parse(TC.Any()) == {'i': 12, 'name': 'Hello world'})
+ self.failUnless(ps.Parse(TC.Any(aslist=True)) == [12, 'Hello world'])
+ def check_any_typed_soap_integer(self):
+ # from zsi developer's guide
+ value = 12
+ d = dict(value=value)
+ d.update(NSDICT)
+ xml = """<tns:i xsi:type="SOAP-ENC:integer" %(xsi)s %(soap)s %(tns)s>%(value)d</tns:i>""" %d
+ ps = ParsedSoap(xml, envelope=False)
+ self.failUnless(ps.Parse(TC.Any()) == value)
+
+ def check_any_typed_xsd_int(self):
+ # from zsi developer's guide
+ value = 12
+ d = dict(value=value)
+ d.update(NSDICT)
+ xml = """<tns:i xsi:type="xsd:int" %(xsi)s %(soap)s %(tns)s %(xsd)s>%(value)d</tns:i>""" %d
+ ps = ParsedSoap(xml, envelope=False)
+ self.failUnless(ps.Parse(TC.Any()) == value)
+
+ def check_any_typed_nonNegativeInteger(self):
+ # from zsi developer's guide
+ value = 12
+ d = dict(value=value)
+ d.update(NSDICT)
+ xml = """<tns:i xsi:type="xsd:nonNegativeInteger" %(xsi)s %(soap)s %(tns)s %(xsd)s>%(value)d</tns:i>""" %d
+ ps = ParsedSoap(xml, envelope=False)
+ self.failUnless(ps.Parse(TC.Any()) == value)
+
+ def check_any_untyped_int(self):
+ # from zsi developer's guide
+ d = dict(value=12)
+ d.update(NSDICT)
+ xml = """<tns:i %(tns)s>12</tns:i>""" %NSDICT
+ ps = ParsedSoap(xml, envelope=False)
+ self.failUnlessRaises(EvaluateException, ps.Parse, TC.Any())
+
+
+#
+# Creates permutation of test options: "check", "check_any", etc
+#
+_SEP = '_'
+for t in [i[0].split(_SEP) for i in filter(lambda i: callable(i[1]), AnyTestCase.__dict__.items())]:
+ test = ''
+ for f in t:
+ test += f
+ if globals().has_key(test): test += _SEP; continue
+ def _closure():
+ name = test
+ def _makeTestSuite():
+ suite = unittest.TestSuite()
+ suite.addTest(unittest.makeSuite(AnyTestCase, name))
+ return suite
+ return _makeTestSuite
+
+ globals()[test] = _closure()
+ test += _SEP
+
+makeTestSuite = check
+
def main():
unittest.main(defaultTest="makeTestSuite")
-
if __name__ == "__main__" : main()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|