A fork of https://github.com/Synerty/SOAPpy-py3 This is a working tree till fixes get imported upstream.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

3808 lines
137 KiB

  1. #!/usr/bin/env python
  2. ################################################################################
  3. #
  4. # A bunch of regression type tests for the builder and parser.
  5. #
  6. ################################################################################
  7. ident = '$Id: SOAPtest.py,v 1.19 2004/04/01 13:25:46 warnes Exp $'
  8. import urllib
  9. import sys
  10. import unittest
  11. import re
  12. sys.path.insert(1, "..")
  13. from SOAPpy import *
  14. config=Config
  15. config.strict_range=1
  16. # run these tests with this variable set both to 1 and 0
  17. config.simplify_objects=0
  18. # as borrowed from jake.soapware.org for float compares.
  19. def nearlyeq(a, b, prec = 1e-7):
  20. return abs(a - b) <= abs(a) * prec
  21. # helper
  22. def negfloat(x):
  23. return float(x) * -1.0
  24. class Book(structType):
  25. def __init__(self):
  26. self.title = "Title of a book"
  27. structType.__init__(self)
  28. class Person(structType):
  29. def __init__(self):
  30. self.age = "49"
  31. self.height = "5.5"
  32. structType.__init__(self)
  33. class Result(structType):
  34. def __init__(self):
  35. structType.__init__(self, name = 'Result')
  36. self.Book = Book()
  37. self.Person = Person()
  38. class one:
  39. def __init__(self):
  40. self.str = "one"
  41. class two:
  42. def __init__(self):
  43. self.str = "two"
  44. class three:
  45. def __init__(self):
  46. self.str = "three"
  47. ws = ' \t\r\n'
  48. N = None
  49. class SOAPTestCase(unittest.TestCase):
  50. # big message
  51. def notestBigMessage(self):
  52. x=[]
  53. for y in string.lowercase:
  54. x.append(y*999999)
  55. buildSOAP(x)
  56. # test arrayType
  57. def testArrayType(self):
  58. x = structType( {"name":"widg1","quantity":200,
  59. "price":decimalType(45.99),
  60. "_typename":"LineItem"})
  61. y = buildSOAP([x, x])
  62. # could be parsed using an XML parser?
  63. self.failUnless(string.find(y, "LineItem")>-1)
  64. # test arguments ordering
  65. def testOrdering(self):
  66. x = buildSOAP(method="newCustomer", namespace="urn:customer", \
  67. kw={"name":"foo1", "address":"bar"}, \
  68. config=SOAPConfig(argsOrdering={"newCustomer":("address", "name")}))
  69. # could be parsed using an XML parser?
  70. self.failUnless(string.find(x, "<address ")<string.find(x, "<name "))
  71. x = buildSOAP(method="newCustomer", namespace="urn:customer", \
  72. kw={"name":"foo1", "address":"bar"}, \
  73. config=SOAPConfig(argsOrdering={"newCustomer":("name", "address")}))
  74. # could be parsed using an XML parser?
  75. self.failUnless(string.find(x, "<address ")>string.find(x, "<name "))
  76. # test struct
  77. def testStructIn(self):
  78. x = '''<?xml version="1.0" encoding="utf-8"?>
  79. <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  80. <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  81. <SomeMethod>
  82. <Result>
  83. <Book>
  84. <title>My Life and Work</title>
  85. </Book>
  86. <Person>
  87. <name>Henry Ford</name>
  88. <age> 49 </age>
  89. <height> 5.5 </height>
  90. </Person>
  91. </Result>
  92. </SomeMethod>
  93. </soap:Body>
  94. </soap:Envelope>
  95. '''
  96. # parse rules
  97. pr = {'SomeMethod':
  98. {'Result':
  99. {'Book': {'title':(NS.XSD, "string")},
  100. 'Person': {'age':(NS.XSD, "int"),
  101. 'height':negfloat}
  102. }
  103. }
  104. }
  105. y = parseSOAPRPC(x, rules=pr)
  106. if config.simplify_objects:
  107. self.assertEquals(y['Result']['Person']['age'], 49);
  108. self.assertEquals(y['Result']['Person']['height'], -5.5);
  109. else:
  110. self.assertEquals(y.Result.Person.age, 49);
  111. self.assertEquals(y.Result.Person.height, -5.5);
  112. # Try the reverse
  113. def testStructOut(self):
  114. x = buildSOAP(Result())
  115. def testIntFloat(self):
  116. x='''<SOAP-ENV:Envelope
  117. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  118. xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  119. xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
  120. xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  121. SOAP-ENV:encodingStyle="http://schemas.microsoft.com/soap/encoding/clr/1.0
  122. http://schemas.xmlsoap.org/soap/encoding/"
  123. xmlns:i3="http://soapinterop.org/xsd" xmlns:i2="http://soapinterop.org/">
  124. <SOAP-ENV:Body>
  125. <i2:echoStructArray id="ref-1">
  126. <return href="#ref-4"/>
  127. </i2:echoStructArray>
  128. <SOAP-ENC:Array id="ref-4" SOAP-ENC:arrayType="i3:SOAPStruct[3]">
  129. <item href="#ref-5"/>
  130. <item href="#ref-6"/>
  131. <item href="#ref-7"/>
  132. </SOAP-ENC:Array>
  133. <i3:SOAPStruct id="ref-5">
  134. <varString xsi:type="xsd:string">West Virginia</varString>
  135. <varInt xsi:type="xsd:int">-546</varInt>
  136. <varFloat xsi:type="xsd:float">-5.398</varFloat>
  137. </i3:SOAPStruct>
  138. <i3:SOAPStruct id="ref-6">
  139. <varString xsi:type="xsd:string">New Mexico</varString>
  140. <varInt xsi:type="xsd:int">-641</varInt>
  141. <varFloat xsi:type="xsd:float">-9.351</varFloat>
  142. </i3:SOAPStruct>
  143. <i3:SOAPStruct id="ref-7">
  144. <varString xsi:type="xsd:string">Missouri</varString>
  145. <varInt xsi:type="xsd:int">-819</varInt>
  146. <varFloat xsi:type="xsd:float">1.375</varFloat>
  147. </i3:SOAPStruct>
  148. </SOAP-ENV:Body>
  149. </SOAP-ENV:Envelope>'''
  150. y = parseSOAPRPC(x)
  151. if(config.simplify_objects):
  152. self.assertEquals(y['return'][0]['varString'], "West Virginia")
  153. self.assertEquals(y['return'][1]['varInt'], -641)
  154. self.assertEquals(y['return'][2]['varFloat'], 1.375)
  155. else:
  156. self.assertEquals(getattr(y,"return")[0].varString, "West Virginia")
  157. self.assertEquals(getattr(y,"return")[1].varInt, -641)
  158. self.assertEquals(getattr(y,"return")[2].varFloat, 1.375)
  159. def testArray1(self):
  160. x='''<SOAP-ENV:Envelope
  161. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  162. xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  163. xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
  164. xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  165. SOAP-ENV:encodingStyle="http://schemas.microsoft.com/soap/encoding/clr/1.0
  166. http://schemas.xmlsoap.org/soap/encoding/"
  167. xmlns:i3="http://soapinterop.org/xsd" xmlns:i2="http://soapinterop.org/">
  168. <SOAP-ENV:Body>
  169. <i2:echoStructArray id="ref-1">
  170. <return href="#ref-4"/>
  171. </i2:echoStructArray>
  172. <SOAP-ENC:Array id="ref-4" SOAP-ENC:arrayType="i3:SOAPStruct[3]">
  173. <item href="#ref-5"/>
  174. <item href="#ref-6"/>
  175. <item href="#ref-7"/>
  176. </SOAP-ENC:Array>
  177. <i3:SOAPStruct id="ref-5">
  178. <xsd:string>West Virginia</xsd:string>
  179. <xsd:int>-546</xsd:int>
  180. <xsd:float>-5.398</xsd:float>
  181. </i3:SOAPStruct>
  182. <i3:SOAPStruct id="ref-6">
  183. <xsd:string>New Mexico</xsd:string>
  184. <xsd:int>-641</xsd:int>
  185. <xsd:float>-9.351</xsd:float>
  186. </i3:SOAPStruct>
  187. <i3:SOAPStruct id="ref-7">
  188. <xsd:string>Missouri</xsd:string>
  189. <xsd:int>-819</xsd:int>
  190. <xsd:float>1.375</xsd:float>
  191. </i3:SOAPStruct>
  192. </SOAP-ENV:Body>
  193. </SOAP-ENV:Envelope>'''
  194. y = parseSOAPRPC(x)
  195. if(config.simplify_objects):
  196. self.assertEquals(y["return"][0]['string'], "West Virginia")
  197. self.assertEquals(y["return"][1]['int'], -641)
  198. self.assertEquals(y["return"][2]['float'], 1.375)
  199. else:
  200. self.assertEquals(getattr(y,"return")[0].string, "West Virginia")
  201. self.assertEquals(getattr(y,"return")[1].int, -641)
  202. self.assertEquals(getattr(y,"return")[2].float, 1.375)
  203. def testUTF8Encoding1(self):
  204. x = '''<?xml version="1.0" encoding="UTF-8"?>
  205. <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  206. <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsd2="http://www.w3.org/2000/10/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsi2="http://www.w3.org/2000/10/XMLSchema-instance">
  207. <ns0:echoStringArrayResponse xmlns:ns0="http://soapinterop.org/">
  208. <return2 href="#id3"/>
  209. </ns0:echoStringArrayResponse>
  210. <a id="id0" xmlns:ns0="http://soapinterop.org/" xsi2:type="xsd:string" xsi:type="xsd:string"></a>
  211. <a id="id1" xmlns:ns0="http://soapinterop.org/" xsi2:type="xsd:string" xsi:type="xsd:string">Hello</a>
  212. <a id="id2" xmlns:ns0="http://soapinterop.org/" xsi2:type="xsd:string" xsi:type="xsd:string">\'&lt;&amp;&gt;&quot;</a>
  213. <return2 SOAP-ENC:arrayType="xsd:string[3]" id="id3" xmlns:ns0="http://soapinterop.org/">
  214. <a href="#id0"/>
  215. <a href="#id1"/>
  216. <a href="#id2"/>
  217. </return2>
  218. </SOAP-ENV:Body></SOAP-ENV:Envelope>'''
  219. y = parseSOAPRPC(x)
  220. if config.simplify_objects:
  221. self.assertEquals(y['return2'][1], "Hello")
  222. else:
  223. self.assertEquals(y.return2[1], "Hello")
  224. def testUTF8Encoding2(self):
  225. x = '''<?xml version="1.0" encoding="UTF-8"?>
  226. <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  227. <SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
  228. <ns0:echoStringArrayResponse xmlns:ns0="http://soapinterop.org/">
  229. <a xsi:type="xsd:string"></a>
  230. <a xsi:type="xsd:string">Hello</a>
  231. <a xsi:type="xsd:string">\'&lt;&amp;&gt;&quot;</a>
  232. <b xsi:type="xsd:string">Goodbye</b>
  233. </ns0:echoStringArrayResponse>
  234. </SOAP-ENV:Body>
  235. </SOAP-ENV:Envelope>'''
  236. y = parseSOAPRPC(x)
  237. self.assertEquals(type(y.a), type([]))
  238. self.assertEquals(type(y.b), type(''))
  239. self.assertEquals(type(y._getItemAsList('a')), type([]))
  240. self.assertEquals(type(y._getItemAsList('b')), type([]))
  241. self.assertEquals(y.b, 'Goodbye')
  242. self.assertEquals(y.a, ['', 'Hello', '\'<&>"'])
  243. self.assertEquals(y._getItemAsList('b'), ['Goodbye'])
  244. self.assertEquals(y._getItemAsList('c'), [])
  245. self.assertEquals(y._getItemAsList('c', 'hello'), 'hello')
  246. def testUTF8Encoding2(self):
  247. x = '''<?xml version="1.0" encoding="UTF-8"?>
  248. <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  249. <SOAP-ENV:Body
  250. SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
  251. xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
  252. xmlns:xsd="http://www.w3.org/1999/XMLSchema"
  253. xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
  254. <a1 SOAP-ENC:root="1">Hello</a1>
  255. <a2 SOAP-ENC:root="0" id="id">\'&lt;&amp;&gt;&quot;</a2>
  256. <a3>Goodbye</a3>
  257. </SOAP-ENV:Body>
  258. </SOAP-ENV:Envelope>'''
  259. y = parseSOAP(x)
  260. self.assertEquals(y.a1, 'Hello')
  261. self.assertEquals(y.a3, 'Goodbye')
  262. self.failIf(hasattr(y, 'a2'))
  263. def testUTF8Encoding3(self):
  264. x = '''<?xml version="1.0" encoding="utf-8"?>
  265. <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  266. <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  267. <SomeMethod>
  268. <Result>
  269. <Book>
  270. <title>My Life and Work</title>
  271. <author href="#Person-1"/>
  272. </Book>
  273. <Person id="Person-1">
  274. <name>Henry Ford</name>
  275. <address href="#Address-2"/>
  276. </Person>
  277. <Address id="Address-2">
  278. <email>mailto:henryford@hotmail.com</email>
  279. <web>http://www.henryford.com</web>
  280. <pers href="#Person-1"/>
  281. </Address>
  282. </Result>
  283. </SomeMethod>
  284. </soap:Body>
  285. </soap:Envelope>
  286. '''
  287. y = parseSOAPRPC(x)
  288. if config.simplify_objects:
  289. self.assertEquals(y['Result']['Book']['author']['name'], "Henry Ford")
  290. self.assertEquals(y['Result']['Book']['author']['address']['web'], "http://www.henryford.com")
  291. self.assertEquals(y['Result']['Book']['author']['address']['pers']['name'], "Henry Ford")
  292. else:
  293. self.assertEquals(y.Result.Book.author.name, "Henry Ford")
  294. self.assertEquals(y.Result.Book.author.address.web, "http://www.henryford.com")
  295. self.assertEquals(y.Result.Book.author.address.pers.name, "Henry Ford")
  296. # ref example
  297. def testRef(self):
  298. x = '''<?xml version="1.0" encoding="utf-8"?>
  299. <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  300. <soap:Body soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  301. <echoFloatArrayResponse xmlns="http://soapinterop.org/">
  302. <Return href="#i1" xmlns="" />
  303. </echoFloatArrayResponse>
  304. <soapenc:Array id="i1" soapenc:arrayType="xsd:float[4]">
  305. <Item>0</Item>
  306. <Item>1</Item>
  307. <Item>-1</Item>
  308. <Item>3853.33325</Item>
  309. </soapenc:Array>
  310. </soap:Body>
  311. </soap:Envelope>
  312. '''
  313. y = parseSOAPRPC(x)
  314. if config.simplify_objects:
  315. self.assertEquals(y['Return'][0], 0)
  316. self.assertEquals(y['Return'][1], 1)
  317. self.assertEquals(y['Return'][2], -1)
  318. self.failUnless(nearlyeq(y['Return'][3], 3853.33325))
  319. else:
  320. self.assertEquals(y.Return[0], 0)
  321. self.assertEquals(y.Return[1], 1)
  322. self.assertEquals(y.Return[2], -1)
  323. self.failUnless(nearlyeq(y.Return[3], 3853.33325))
  324. # Make sure passing in our own bodyType works.
  325. def testBodyType(self):
  326. a = [23, 42]
  327. b = bodyType()
  328. b.a = b.b = a
  329. x = buildSOAP(b)
  330. y = parseSOAP(x)
  331. self.assertEquals(id(y.a), id(y.b))
  332. self.assertEquals(y.a, a)
  333. self.assertEquals(y.b, a)
  334. # Test Envelope versioning (see section 4.1.2 of http://www.w3.org/TR/SOAP).
  335. def testEnvelopeVersioning(self):
  336. xml = '''<SOAP-ENV:Envelope
  337. SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
  338. xmlns:xsd="http://www.w3.org/1999/XMLSchema"
  339. xmlns:SOAP-ENV="http://new/envelope/version/"
  340. xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance"
  341. xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
  342. <SOAP-ENV:Body>
  343. <_1 xsi:type="xsd:int" SOAP-ENC:root="1">1</_1>
  344. </SOAP-ENV:Body>
  345. </SOAP-ENV:Envelope>'''
  346. try:
  347. parseSOAP(xml)
  348. except Exception, e:
  349. self.failUnless(isinstance(e, faultType))
  350. self.assertEquals(e.faultcode, '%s:VersionMismatch' % NS.ENV_T)
  351. self.failIf(hasattr(e, 'detail'))
  352. # Big terrible ordered data with attributes test.
  353. def testBigOrderedData(self):
  354. data = '''<?xml version="1.0" encoding="UTF-8" ?>
  355. <Envelope xmlns="http://schemas.xmlsoap.org/soap/envelope/">
  356. <Body>
  357. <replyBlock generic="1.0" attrib1="false" attrib2='hello'>
  358. <itemList>
  359. <mainItem mainattrib1='uno'>
  360. <name>first_main_item</name>
  361. <description>whatever etc.</description>
  362. <infoList>
  363. <itemInfo a1='123' a2='abc'>
  364. <name>unoItem1</name>
  365. </itemInfo>
  366. <itemInfo a1='456' a2='def'>
  367. <name>unoItem2</name>
  368. </itemInfo>
  369. <itemInfo a1='789' a2='ghi'>
  370. <name>unoItem3</name>
  371. </itemInfo>
  372. </infoList>
  373. </mainItem>
  374. <mainItem mainattrib1='dos'>
  375. <name>second_main_item</name>
  376. <description>whatever etc.</description>
  377. <infoList>
  378. <itemInfo a1='3123' a2='3abc'>
  379. <name>dosItem1</name>
  380. </itemInfo>
  381. <itemInfo a1='3456' a2='3def'>
  382. <name>dosItem2</name>
  383. </itemInfo>
  384. <itemInfo a1='3789' a2='3ghi'>
  385. <name>dosItem3</name>
  386. </itemInfo>
  387. </infoList>
  388. </mainItem>
  389. </itemList>
  390. <itemList>
  391. <mainItem mainattrib1='single'>
  392. <name>single_main_item</name>
  393. <description>whatever etc.</description>
  394. <infoList>
  395. <itemInfo a1='666' a2='xxx'>
  396. <name>singleItem1</name>
  397. </itemInfo>
  398. </infoList>
  399. </mainItem>
  400. </itemList>
  401. </replyBlock>
  402. </Body>
  403. </Envelope>'''
  404. x = parseSOAP(data)
  405. # print ".>",x.replyBlock.itemList._ns
  406. y = buildSOAP(x)
  407. def testEnvelope1(self):
  408. my_xml2 = '''
  409. <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  410. <SOAP-ENV:Header>
  411. <t:Transaction xmlns:t="some-URI" SOAP-ENV:mustUnderstand="1">
  412. 5
  413. </t:Transaction>
  414. </SOAP-ENV:Header>
  415. <SOAP-ENV:Body>
  416. <m:GetLastTradePriceResponse xmlns:m="Some-URI">
  417. <PriceAndVolume>
  418. <LastTradePrice>
  419. 34.5
  420. </LastTradePrice>
  421. <DayVolume>
  422. 10000
  423. </DayVolume>
  424. </PriceAndVolume>
  425. </m:GetLastTradePriceResponse>
  426. </SOAP-ENV:Body>
  427. </SOAP-ENV:Envelope>
  428. '''
  429. (x,h) = parseSOAPRPC(my_xml2,header=1)
  430. def testEnvelope2(self):
  431. x ='''
  432. <V:Envelope
  433. xmlns:V="http://schemas.xmlsoap.org/soap/envelope/"
  434. xmlns:C="http://schemas.xmlsoap.org/soap/encoding/"
  435. xmlns:i="http://www.w3.org/1999/XMLSchema-instance"
  436. xmlns:d="http://www.w3.org/1999/XMLSchema"
  437. V:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  438. <V:Body>
  439. <m:echoStructArray
  440. xmlns:m="urn:xmethodsInterop">
  441. <inputStructArray
  442. i:type="C:Array"
  443. C:arrayType="ns3:SOAPStruct[0]"
  444. xmlns:ns3="http://soapinterop.org/xsd"/>
  445. </m:echoStructArray>
  446. </V:Body>
  447. </V:Envelope>'''
  448. x = parseSOAPRPC(x)
  449. def testEnvelope3(self):
  450. x = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  451. <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
  452. <SOAP-ENV:Body>
  453. <m:echoStringResponse xmlns:m="http://soapinterop.org/">
  454. <Result name="fred">hello</Result>
  455. </m:echoStringResponse>
  456. </SOAP-ENV:Body>
  457. </SOAP-ENV:Envelope>
  458. '''
  459. x, a = parseSOAPRPC(x, attrs = 1)
  460. if config.simplify_objects:
  461. self.assertEquals(a[id(x['Result'])][(None, 'name')], 'fred')
  462. else:
  463. self.assertEquals(a[id(x.Result)][(None, 'name')], 'fred')
  464. def testParseException(self):
  465. x='''<SOAP-ENV:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.microsoft.com/soap/encoding/clr/1.0 http://schemas.xmlsoap.org/soap/encoding/" xmlns:a1="http://schemas.microsoft.com/clr/ns/System.Runtime.Serialization.Formatters">
  466. <SOAP-ENV:Body>
  467. <SOAP-ENV:Fault id="ref-1">
  468. <faultcode id="ref-2">SOAP-ENV:Server</faultcode>
  469. <faultstring id="ref-3">Exception thrown on Server</faultstring>
  470. <detail xsi:type="a1:ServerFault">
  471. <exceptionType id="ref-4">System.Runtime.Serialization.SerializationException, mscorlib, Version=1.0.2411.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</exceptionType>
  472. <message id="ref-5">Soap Parser Error System.Runtime.Serialization.SerializationException: Parse Error, xsd type not valid: Array
  473. at System.Runtime.Serialization.Formatters.Soap.SoapHandler.ProcessGetType(String value, String xmlKey)
  474. at System.Runtime.Serialization.Formatters.Soap.SoapHandler.ProcessType(ParseRecord pr, ParseRecord objectPr)
  475. at System.Runtime.Serialization.Formatters.Soap.SoapHandler.ProcessAttributes(ParseRecord pr, ParseRecord objectPr)
  476. at System.Runtime.Serialization.Formatters.Soap.SoapHandler.StartElement(String prefix, String name, String urn)
  477. at System.XML.XmlParser.ParseElement()
  478. at System.XML.XmlParser.ParseTag()
  479. at System.XML.XmlParser.Parse()
  480. at System.XML.XmlParser.Parse0()
  481. at System.XML.XmlParser.Run()</message>
  482. <stackTrace id="ref-6"> at System.Runtime.Serialization.Formatters.Soap.SoapHandler.Error(IXmlProcessor p, Exception ex)
  483. at System.XML.XmlParser.Run()
  484. at System.Runtime.Serialization.Formatters.Soap.SoapParser.Run()
  485. at System.Runtime.Serialization.Formatters.Soap.ObjectReader.Deserialize(HeaderHandler handler, ISerParser serParser)
  486. at System.Runtime.Serialization.Formatters.Soap.SoapFormatter.Deserialize(Stream serializationStream, HeaderHandler handler)
  487. at System.Runtime.Remoting.Channels.CoreChannel.DeserializeMessage(String mimeType, Stream xstm, Boolean methodRequest, IMessage msg, Header[] h)
  488. at System.Runtime.Remoting.Channels.SoapServerFormatterSink.ProcessMessage(IServerChannelSinkStack sinkStack, ITransportHeaders requestHeaders, Stream requestStream, IMessage&#38; msg, ITransportHeaders&#38; responseHeaders, Stream&#38; responseStream)</stackTrace>
  489. </detail>
  490. </SOAP-ENV:Fault>
  491. </SOAP-ENV:Body>
  492. </SOAP-ENV:Envelope>
  493. '''
  494. z = parseSOAPRPC(x)
  495. self.assertEquals(z.__class__,faultType)
  496. self.assertEquals(z.faultstring, "Exception thrown on Server")
  497. def testFlatEnvelope(self):
  498. x = '''<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  499. <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"><SOAP-ENV:Body><m:echoStringResponse xmlns:m="http://soapinterop.org/"><Result></Result></m:echoStringResponse></SOAP-ENV:Body></SOAP-ENV:Envelope>
  500. '''
  501. z = parseSOAPRPC(x)
  502. if config.simplify_objects:
  503. self.assertEquals(type(z['Result']), type(''))
  504. else:
  505. self.assertEquals(type(z.Result), type(''))
  506. def testNumericArray(self):
  507. x = [1,2,3,4,5]
  508. y = buildSOAP(x)
  509. z = parseSOAPRPC(y)
  510. self.assertEquals(x, z)
  511. def testStringArray(self):
  512. x = ["cayce", "asd", "buy"]
  513. y = buildSOAP(x)
  514. z = parseSOAPRPC(y)
  515. self.assertEquals(x, z)
  516. def testStringArray1(self):
  517. x = arrayType(['a', 'b', 'c'])
  518. y = buildSOAP(x)
  519. z = parseSOAP(y)
  520. if config.simplify_objects:
  521. self.assertEquals(z.v1._elemsname, 'item')
  522. self.assertEquals(z.v1, x)
  523. else:
  524. self.assertEquals(z['v1']['_elemsname'], 'item')
  525. self.assertEquals(z['v1'], x)
  526. def testStringArray2(self):
  527. x = arrayType(['d', 'e', 'f'], elemsname = 'elementals')
  528. y = buildSOAP(x)
  529. z = parseSOAP(y)
  530. if config.simplify_objects:
  531. self.assertEquals(z.v1._elemsname, 'elementals')
  532. self.assertEquals(z.v1, x)
  533. else:
  534. self.assertEquals(z['v1']['_elemsname'], 'elementals')
  535. self.assertEquals(z['v1'], x)
  536. def testInt1(self):
  537. my_xml = '''
  538. <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
  539. <SOAP-ENV:Body>
  540. <m:getStateName xmlns:m="http://www.soapware.org/">
  541. <statenum xsi:type="xsd:int">41</statenum>
  542. </m:getStateName>
  543. </SOAP-ENV:Body>
  544. </SOAP-ENV:Envelope>
  545. '''
  546. s = parseSOAPRPC(my_xml)
  547. if config.simplify_objects:
  548. self.assertEquals(s['statenum'], 41)
  549. self.assertEquals(type(s['statenum']), type(0))
  550. else:
  551. self.assertEquals(s.statenum, 41)
  552. self.assertEquals(type(s.statenum), type(0))
  553. def testInt2(self):
  554. my_xml_ns = '''
  555. <XSOAP-ENV:Envelope XSOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:XSOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:XSOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:Xxsd="http://www.w3.org/1999/XMLSchema" xmlns:Xxsi="http://www.w3.org/1999/XMLSchema-instance">
  556. <XSOAP-ENV:Body>
  557. <m:getStateName xmlns:m="http://www.soapware.org/">
  558. <statenum Xxsi:type="Xxsd:int">41</statenum>
  559. </m:getStateName>
  560. </XSOAP-ENV:Body>
  561. </XSOAP-ENV:Envelope>
  562. '''
  563. s = parseSOAPRPC(my_xml_ns)
  564. if config.simplify_objects:
  565. self.assertEquals(s['statenum'], 41, "NS one failed")
  566. self.assertEquals(type(s['statenum']), type(0))
  567. else:
  568. self.assertEquals(s.statenum, 41, "NS one failed")
  569. self.assertEquals(type(s.statenum), type(0))
  570. def testPriceAndVolume(self):
  571. my_xml2 = '''
  572. <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
  573. <SOAP-ENV:Header>
  574. <t:Transaction xmlns:t="some-URI" SOAP-ENV:mustUnderstand="1">
  575. 5
  576. </t:Transaction>
  577. </SOAP-ENV:Header>
  578. <SOAP-ENV:Body>
  579. <m:GetLastTradePriceResponse xmlns:m="Some-URI">
  580. <PriceAndVolume>
  581. <LastTradePrice>
  582. 34.5
  583. </LastTradePrice>
  584. <DayVolume>
  585. 10000
  586. </DayVolume>
  587. </PriceAndVolume>
  588. </m:GetLastTradePriceResponse>
  589. </SOAP-ENV:Body>
  590. </SOAP-ENV:Envelope>
  591. '''
  592. s = parseSOAPRPC(my_xml2)
  593. if config.simplify_objects:
  594. self.assertEquals(s['PriceAndVolume']['LastTradePrice'].strip(), "34.5")
  595. self.assertEquals(s['PriceAndVolume']['DayVolume'].strip(), "10000")
  596. else:
  597. self.assertEquals(s.PriceAndVolume.LastTradePrice.strip(), "34.5")
  598. self.assertEquals(s.PriceAndVolume.DayVolume.strip(), "10000")
  599. def testInt3(self):
  600. my_xml3 = '''
  601. <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
  602. <SOAP-ENV:Body>
  603. <Bounds>
  604. <param>
  605. <lowerBound xsi:type="xsd:int"> 18 </lowerBound>
  606. <upperBound xsi:type="xsd:int"> 139</upperBound>
  607. </param>
  608. </Bounds>
  609. </SOAP-ENV:Body>
  610. </SOAP-ENV:Envelope>
  611. '''
  612. s = parseSOAPRPC(my_xml3)
  613. if config.simplify_objects:
  614. self.assertEquals(s['param']['lowerBound'], 18)
  615. self.assertEquals(s['param']['upperBound'], 139)
  616. else:
  617. self.assertEquals(s.param.lowerBound, 18)
  618. self.assertEquals(s.param.upperBound, 139)
  619. def testBoolean(self):
  620. my_xml4 = '''
  621. <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
  622. <SOAP-ENV:Body>
  623. <Bounds>
  624. <param SOAP-ENC:arrayType="xsd:ur-type[4]" xsi:type="SOAP-ENC:Array"><item xsi:type="xsd:int">12</item>
  625. <item xsi:type="xsd:string">Egypt</item>
  626. <item xsi:type="xsd:boolean">0</item>
  627. <item xsi:type="xsd:int">-31</item>
  628. </param>
  629. <param1 xsi:null="1"></param1>
  630. <param2 xsi:null="true"></param2>
  631. <param3 xsi:type="xsd:int" xsi:null="false">7</param3>
  632. </Bounds>
  633. </SOAP-ENV:Body>
  634. </SOAP-ENV:Envelope>
  635. '''
  636. s = parseSOAPRPC(my_xml4)
  637. if config.simplify_objects:
  638. self.assertEquals(s['param'][0], 12)
  639. self.assertEquals(s['param'][1], "Egypt")
  640. self.assertEquals(s['param'][2], 0)
  641. self.assertEquals(s['param'][3], -31)
  642. self.assertEquals(s['param1'], None)
  643. self.assertEquals(s['param2'], None)
  644. self.assertEquals(s['param3'], 7)
  645. else:
  646. self.assertEquals(s.param[0], 12)
  647. self.assertEquals(s.param[1], "Egypt")
  648. self.assertEquals(s.param[2], 0)
  649. self.assertEquals(s.param[3], -31)
  650. self.assertEquals(s.param1, None)
  651. self.assertEquals(s.param2, None)
  652. self.assertEquals(s.param3, 7)
  653. def testFault(self):
  654. my_xml5 = '''
  655. <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
  656. <SOAP-ENV:Body>
  657. <SOAP-ENV:Fault>
  658. <faultcode>SOAP-ENV:Client</faultcode>
  659. <faultstring>Cant call getStateName because there are too many parameters.</faultstring>
  660. </SOAP-ENV:Fault>
  661. </SOAP-ENV:Body>
  662. </SOAP-ENV:Envelope>
  663. '''
  664. s = parseSOAPRPC(my_xml5)
  665. self.assertEquals(s.__class__, faultType)
  666. self.assertEquals(s.faultcode, "SOAP-ENV:Client")
  667. def testArray2(self):
  668. my_xml6 = '''
  669. <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
  670. <SOAP-ENV:Body>
  671. <h SOAP-ENC:arrayType="xsd:ur-type[6]" xsi:type="SOAP-ENC:Array">
  672. <item xsi:type="xsd:int">5</item>
  673. <item xsi:type="xsd:int">3</item>
  674. <item xsi:type="xsd:int">2</item>
  675. <item xsi:type="xsd:string">monkey</item>
  676. <item xsi:type="xsd:string">cay</item>
  677. <item>
  678. <cat xsi:type="xsd:string">hello</cat>
  679. <ferret SOAP-ENC:arrayType="xsd:ur-type[6]" xsi:type="SOAP-ENC:Array">
  680. <item xsi:type="xsd:int">5</item>
  681. <item xsi:type="xsd:int">4</item>
  682. <item xsi:type="xsd:int">3</item>
  683. <item xsi:type="xsd:int">2</item>
  684. <item xsi:type="xsd:int">1</item>
  685. <item>
  686. <cow xsi:type="xsd:string">moose</cow>
  687. </item>
  688. </ferret>
  689. <monkey xsi:type="xsd:int">5</monkey>
  690. </item>
  691. </h>
  692. </SOAP-ENV:Body>
  693. </SOAP-ENV:Envelope>
  694. '''
  695. q = parseSOAPRPC(my_xml6)
  696. self.assertEquals(q[0], 5)
  697. self.assertEquals(q[1], 3)
  698. self.assertEquals(q[2], 2)
  699. self.assertEquals(q[3], 'monkey')
  700. self.assertEquals(q[4], 'cay')
  701. x = q[5]
  702. if config.simplify_objects:
  703. self.assertEquals(x['monkey'], 5)
  704. self.assertEquals(x['cat'], "hello")
  705. self.assertEquals(x['ferret'][0], 5)
  706. self.assertEquals(x['ferret'][3], 2)
  707. self.assertEquals(x['ferret'][5]['cow'], "moose")
  708. else:
  709. self.assertEquals(x.monkey, 5)
  710. self.assertEquals(x.cat, "hello")
  711. self.assertEquals(x.ferret[0], 5)
  712. self.assertEquals(x.ferret[3], 2)
  713. self.assertEquals(x.ferret[5].cow, "moose")
  714. def testArray3(self):
  715. x = arrayType([5,4,3,21], "spam")
  716. y = buildSOAP(x)
  717. z = parseSOAPRPC(y)
  718. self.assertEquals(x, z)
  719. # test struct
  720. def testStruct(self):
  721. x = structType(name = "eggs")
  722. x.test = 5
  723. y = buildSOAP(x)
  724. z = parseSOAPRPC(y)
  725. if config.simplify_objects:
  726. self.assertEquals( x['test'], z['test'] )
  727. else:
  728. self.assertEquals( x.test, z.test )
  729. # test faults
  730. def testFault1(self):
  731. x = faultType("ServerError","Howdy",[5,4,3,2,1])
  732. y = buildSOAP(x)
  733. z = parseSOAPRPC(y)
  734. self.assertEquals( x.faultcode , z.faultcode)
  735. self.assertEquals( x.faultstring , z.faultstring)
  736. self.assertEquals( x.detail , z.detail)
  737. # Test the recursion
  738. def testRecursion(self):
  739. o = one()
  740. t = two()
  741. o.t = t
  742. t.o = o
  743. tre = three()
  744. tre.o = o
  745. tre.t = t
  746. x = buildSOAP(tre)
  747. y = parseSOAPRPC(x)
  748. if config.simplify_objects:
  749. self.assertEquals( y['t']['o']['t']['o']['t']['o']['t']['str'] , "two")
  750. else:
  751. self.assertEquals( y.t.o.t.o.t.o.t.str , "two")
  752. # Test the recursion with structs
  753. def testRecursionWithStructs(self):
  754. o = structType("one")
  755. t = structType("two")
  756. o.t = t
  757. o.str = "one"
  758. t.o = o
  759. t.str = "two"
  760. tre = structType("three")
  761. tre.o = o
  762. tre.t = t
  763. tre.str = "three"
  764. x = buildSOAP(tre)
  765. y = parseSOAPRPC(x)
  766. if config.simplify_objects:
  767. self.assertEquals( y['t']['o']['t']['o']['t']['o']['t']['str'] , "two")
  768. else:
  769. self.assertEquals( y.t.o.t.o.t.o.t.str , "two")
  770. def testAmp(self):
  771. m = "Test Message <tag> & </tag>"
  772. x = structType("test")
  773. x.msg = m
  774. y = buildSOAP(x)
  775. z = parseSOAPRPC(y)
  776. if config.simplify_objects:
  777. self.assertEquals( m , z['msg'])
  778. else:
  779. self.assertEquals( m , z.msg)
  780. def testInt4(self):
  781. my_xml7 = '''
  782. <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
  783. <SOAP-ENV:Body>
  784. <Bounds>
  785. <param>
  786. <lowerBound xsi:type="xsd:int"> 18 </lowerBound>
  787. <upperBound xsi:type="xsd:int"> 139</upperBound>
  788. </param>
  789. </Bounds>
  790. </SOAP-ENV:Body>
  791. </SOAP-ENV:Envelope>
  792. '''
  793. x = parseSOAPRPC(my_xml7)
  794. y = buildSOAP(x)
  795. # Does buildSOAP require a valid encoding?
  796. def testBuildSOAPEncoding(self):
  797. try:
  798. x = buildSOAP('hello', encoding = 'gleck')
  799. except LookupError, e:
  800. if str (e)[0:16] != 'unknown encoding': raise
  801. x = None
  802. except:
  803. print "Got unexpected exception: %s %s" % tuple (sys.exc_info ()[0:2])
  804. x = ''
  805. self.assertEquals( x , None)
  806. # Does SOAPProxy require a valid encoding?
  807. def testSOAPProxyEncoding(self):
  808. try:
  809. x = SOAPProxy('', encoding = 'gleck')
  810. except LookupError, e:
  811. if str (e)[0:16] != 'unknown encoding': raise
  812. x = None
  813. except:
  814. print "Got unexpected exception: %s %s" % tuple (sys.exc_info ()[0:2])
  815. x = ''
  816. self.assertEquals( x , None)
  817. # Does SOAPServer require a valid encoding?
  818. def testSOAPServerEncoding(self):
  819. try:
  820. x = SOAPServer(('localhost', 0), encoding = 'gleck')
  821. except LookupError, e:
  822. if str (e)[0:16] != 'unknown encoding': raise
  823. x = None
  824. except:
  825. print "Got unexpected exception: %s %s" % tuple (sys.exc_info ()[0:2])
  826. x = ''
  827. self.assertEquals( x , None)
  828. def testEncodings(self):
  829. encodings = ('US-ASCII', 'ISO-8859-1', 'UTF-8', 'UTF-16')
  830. tests = ('A', u'\u0041')
  831. for t in tests:
  832. for i in range (len (encodings)):
  833. x = buildSOAP (t, encoding = encodings[i])
  834. y = parseSOAPRPC (x)
  835. self.assertEquals( y , t)
  836. tests = (u'\u00a1',)
  837. for t in tests:
  838. for i in range (len (encodings)):
  839. try:
  840. x = buildSOAP (t, encoding = encodings[i])
  841. except:
  842. if i > 0: raise
  843. continue
  844. y = parseSOAPRPC (x)
  845. self.assertEquals( y , t)
  846. tests = (u'\u01a1', u'\u2342')
  847. for t in tests:
  848. for i in range (len (encodings)):
  849. try:
  850. x = buildSOAP (t, encoding = encodings[i])
  851. except:
  852. if i > 1: raise
  853. continue
  854. y = parseSOAPRPC (x)
  855. self.assertEquals( y , t)
  856. def build_xml(self, schema, type, value, attrs = ''):
  857. return '''<?xml version="1.0" encoding="UTF-8"?>
  858. <SOAP-ENV:Envelope
  859. SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
  860. xmlns:xsd="%(schema)s"
  861. xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
  862. xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
  863. <SOAP-ENV:Body>
  864. <_1 xsi:type="xsd:%(type)s"%(attrs)s>%(value)s</_1>
  865. </SOAP-ENV:Body>
  866. </SOAP-ENV:Envelope>''' % {'schema': schema, 'type': type, 'value': value,
  867. 'attrs': attrs}
  868. # Make sure the various limits are checked when parsing
  869. def testIntegerLimits(self):
  870. for t, l in SOAPParser.intlimits.items():
  871. try:
  872. parseSOAP(xml % (NS.XSD, t, 'hello'))
  873. raise AssertionError, "parsed %s of 'hello' without error" % t
  874. except AssertionError:
  875. raise
  876. except:
  877. pass
  878. if l[1] != None:
  879. try:
  880. parseSOAP(self.build_xml(NS.XSD, t, l[1] - 1))
  881. raise AssertionError, "parsed %s of %s without error" % \
  882. (t, l[1] - 1)
  883. except AssertionError:
  884. raise
  885. except UnderflowError:
  886. pass
  887. if l[2] != None:
  888. try:
  889. parseSOAP(self.build_xml(NS.XSD, t, l[2] + 1))
  890. raise AssertionError, "parsed %s of %s without error" % \
  891. (t, l[2] + 1)
  892. except AssertionError:
  893. raise
  894. except OverflowError:
  895. pass
  896. # Make sure the various limits are checked when parsing
  897. # Next, floats. Note that chances are good this won't work in any non-Unix Pythons.
  898. def testFloatLimits(self):
  899. for i in \
  900. (
  901. ('float', '-3.402823466391E+38'),
  902. ('float', '3.402823466391E+38'),
  903. ('float', '3.5e+38'),
  904. ('float', '6.9e-46'),
  905. ('double', '-1.7976931348623159E+308'),
  906. ('double', '1.7976931348623159E+308'),
  907. ('double', '1.8e308'),
  908. ('double', '2.4e-324'),
  909. ):
  910. try:
  911. parseSOAP(self.build_xml(NS.XSD, i[0], i[1]))
  912. # Hide this error for now, cause it is a bug in python 2.0 and 2.1
  913. #if not (sys.version_info[0] == 2 and sys.version_info[1] <= 2) \
  914. # and i[1]=='1.7976931348623159E+308':
  915. raise AssertionError, "parsed %s of %s without error" % i
  916. except AssertionError:
  917. raise
  918. except (UnderflowError, OverflowError):
  919. pass
  920. # Make sure we can't instantiate the base classes
  921. def testCannotInstantiateBaseClasses(self):
  922. for t in (anyType, NOTATIONType):
  923. try:
  924. x = t()
  925. raise AssertionError, "instantiated %s directly" % repr(t)
  926. except:
  927. pass
  928. # Try everything that requires initial data without any.
  929. def testMustBeInitialized(self):
  930. for t in (CDATAType, ENTITIESType, ENTITYType, IDType, IDREFType,
  931. IDREFSType, NCNameType, NMTOKENType, NMTOKENSType, NOTATIONType,
  932. NameType, QNameType, anyURIType, base64Type, base64BinaryType,
  933. binaryType, booleanType, byteType, decimalType, doubleType,
  934. durationType, floatType, hexBinaryType, intType, integerType,
  935. languageType, longType, negative_IntegerType, negativeIntegerType,
  936. non_Negative_IntegerType, non_Positive_IntegerType,
  937. nonNegativeIntegerType, nonPositiveIntegerType, normalizedStringType,
  938. positive_IntegerType, positiveIntegerType, shortType, stringType,
  939. timeDurationType, tokenType, unsignedByteType, unsignedIntType,
  940. unsignedLongType, unsignedShortType, untypedType, uriType,
  941. uriReferenceType):
  942. try:
  943. t()
  944. raise AssertionError, "instantiated a %s with no value" % t.__name__
  945. except AssertionError:
  946. raise
  947. except:
  948. pass
  949. def testInstantiations(self):
  950. # string, ENTITY, ID, IDREF, language, Name, NCName,
  951. # NMTOKEN, QName, untypedType
  952. for t in (stringType, ENTITYType, IDType, IDREFType,
  953. languageType, NameType, NCNameType, NMTOKENType,
  954. QNameType, untypedType):
  955. # First some things that shouldn't be taken as the current type
  956. test = (10, (), [], {})
  957. for i in test:
  958. try:
  959. t(i)
  960. raise AssertionError, \
  961. "instantiated a %s with a bad type (%s)" % \
  962. (repr(t), repr(type(i)))
  963. except AssertionError:
  964. raise
  965. except:
  966. pass
  967. # Now some things that should
  968. for i in ('hello', u'goodbye'):
  969. x = t(i)
  970. d = x._marshalData()
  971. if d != i:
  972. raise AssertionError, "expected %s, got %s" % (i, d)
  973. y = buildSOAP(x)
  974. z = parseSOAPRPC(y)
  975. if z != i:
  976. raise AssertionError, "expected %s, got %s" % (i, z)
  977. # ENTITIES, IDREFS, NMTOKENS
  978. for t in (ENTITIESType, IDREFSType, NMTOKENSType):
  979. # First some things that shouldn't be taken as the current type
  980. test = ({}, lambda x: x, ((),), ([],), [{}], [()])
  981. for i in test:
  982. try:
  983. t(i)
  984. raise AssertionError, \
  985. "instantiated a %s with a bad type (%s)" % \
  986. repr(t), repr(type(i))
  987. except AssertionError:
  988. raise
  989. except:
  990. pass
  991. # Now some things that should
  992. for i in ('hello', (), [], ('hello', 'goodbye'), ['aloha', 'guten_tag']):
  993. x = t(i)
  994. d = x._marshalData()
  995. if type(i) in (type(()), type([])):
  996. j = list(i)
  997. else:
  998. j = [i]
  999. k = ' '.join(j)
  1000. if d != k:
  1001. raise AssertionError, "expected %s, got %s" % (k, d)
  1002. y = buildSOAP(x)
  1003. z = parseSOAPRPC(y)
  1004. if z != j:
  1005. raise AssertionError, "expected %s, got %s" % (repr(j), repr(z))
  1006. # uri, uriReference, anyURI
  1007. for t in (uriType, uriReferenceType, anyURIType):
  1008. # First some things that shouldn't be taken as the current type
  1009. test = (10, (), [], {})
  1010. for i in test:
  1011. try:
  1012. t(i)
  1013. raise AssertionError, \
  1014. "instantiated a %s with a bad type (%s)" % \
  1015. t.__name__, repr(type(i))
  1016. except AssertionError:
  1017. raise
  1018. except:
  1019. pass
  1020. # Now some things that should
  1021. for i in ('hello', u'goodbye', '!@#$%^&*()-_=+[{]}\|;:\'",<.>/?`~'):
  1022. x = t(i)
  1023. d = x._marshalData()
  1024. j = urllib.quote(i)
  1025. if d != j:
  1026. raise AssertionError, "expected %s, got %s" % (j, d)
  1027. y = buildSOAP(x)
  1028. z = parseSOAPRPC(y)
  1029. if z != i:
  1030. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  1031. # token First some things that shouldn't be valid because of type
  1032. test = (42, 3.14, (), [], {})
  1033. t = tokenType
  1034. for i in test:
  1035. try:
  1036. t(i)
  1037. raise AssertionError, \
  1038. "instantiated a %s with a bad type (%s)" % (t.__name__, repr(i))
  1039. except AssertionError:
  1040. raise
  1041. except AttributeError:
  1042. pass
  1043. # Now some things that shouldn't be valid because of content
  1044. test = (' hello', 'hello ', 'hel\nlo', 'hel\tlo', 'hel lo', ' \n \t ')
  1045. for i in test:
  1046. try:
  1047. t(i)
  1048. raise AssertionError, \
  1049. "instantiated a %s with a bad value (%s)" % (t.__name__, repr(i))
  1050. except AssertionError:
  1051. raise
  1052. except ValueError:
  1053. pass
  1054. # Now some things that should be valid
  1055. for i in ('', 'hello', u'hello'):
  1056. x = t(i)
  1057. d = x._marshalData()
  1058. if d != i:
  1059. raise AssertionError, "expected %s, got %s" % (i, d)
  1060. y = buildSOAP(x)
  1061. z = parseSOAPRPC(y)
  1062. if z != i and i != '':
  1063. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  1064. #### CDATA, normalizedString
  1065. for t in (CDATAType, normalizedStringType):
  1066. # First some things that shouldn't be valid because of type
  1067. test = (42, 3.14, (), [], {})
  1068. for i in test:
  1069. try:
  1070. t(i)
  1071. raise AssertionError, \
  1072. "instantiated a %s with a bad type (%s)" % \
  1073. (t.__name__, repr(i))
  1074. except AssertionError:
  1075. raise
  1076. except AttributeError:
  1077. pass
  1078. # Now some things that shouldn't be valid because of content
  1079. test = ('hel\nlo', 'hel\rlo', 'hel\tlo', '\n\r\t')
  1080. for i in test:
  1081. try:
  1082. t(i)
  1083. raise AssertionError, \
  1084. "instantiated a %s with a bad value (%s)" % \
  1085. (t.__name__, repr(i))
  1086. except AssertionError:
  1087. raise
  1088. except ValueError:
  1089. pass
  1090. # Now some things that should be valid
  1091. for i in ('', 'hello', u'hello', 'hel lo'):
  1092. x = t(i)
  1093. d = x._marshalData()
  1094. if d != i:
  1095. raise AssertionError, "expected %s, got %s" % (i, d)
  1096. y = buildSOAP(x)
  1097. z = parseSOAPRPC(y)
  1098. if z != i and i != '':
  1099. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  1100. #### boolean
  1101. # First some things that shouldn't be valid
  1102. test = (10, 'hello', (), [], {})
  1103. t = booleanType
  1104. for i in test:
  1105. try:
  1106. t(i)
  1107. raise AssertionError, \
  1108. "instantiated a %s with a bad value (%s)" % (t.__name__, repr(i))
  1109. except AssertionError:
  1110. raise
  1111. except:
  1112. pass
  1113. # Now some things that should
  1114. for i in ((0, 'false'), ('false', 'false'), (1, 'true'),
  1115. ('true', 'true'), (0.0, 'false'), (1.0, 'true')):
  1116. x = t(i[0])
  1117. d = x._marshalData()
  1118. if d != i[1]:
  1119. raise AssertionError, "%s: expected %s, got %s" % (i[0], i[1], d)
  1120. y = buildSOAP(x)
  1121. z = parseSOAPRPC(y)
  1122. j = ('false', 'true')[z]
  1123. if j != i[1]:
  1124. raise AssertionError, "%s: expected %s, got %s" % \
  1125. (i[0], repr(i[1]), repr(j))
  1126. # Now test parsing, both valid and invalid
  1127. test = (('10', None), ('hello', None), ('false', 0), ('FALSE', 0),
  1128. (ws + 'false' + ws, 0), (ws + '0' + ws, 0),
  1129. ('0', 0), ('true', 1), ('TRUE', 1), ('1', 1),
  1130. (ws + 'true' + ws, 1), (ws + '1' + ws, 1))
  1131. for i in test:
  1132. try:
  1133. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  1134. if z != i[1]:
  1135. raise AssertionError, "%s: expected %s, got %s" % \
  1136. (i[0], i[1], repr(z))
  1137. except AssertionError:
  1138. raise
  1139. except:
  1140. if i[1] != None:
  1141. raise AssertionError, \
  1142. "parsing %s as %s threw exception %s:%s" % \
  1143. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  1144. # Can we give it a name and no type?
  1145. #print
  1146. x = t(1, name = 'George', typed = 0)
  1147. #print "x=",x
  1148. y = buildSOAP(x)
  1149. #print "y=",y
  1150. z = parseSOAP(y)
  1151. #print "z=",z
  1152. test = 'true'
  1153. if z.George != test:
  1154. raise AssertionError, "expected %s, got %s" % (repr(test), repr(z))
  1155. # How about some attributes, set in various and sundry manners?
  1156. x = t(1, attrs = {'nonamespaceURI': 1})
  1157. x._setAttrs({(None, 'NonenamespaceURI'): 2,
  1158. ('http://some/namespace', 'namespaceURIattr1'): 3})
  1159. x._setAttr(('http://some/other/namespace', 'namespaceURIattr2'), 4)
  1160. self.assertEquals( x._getAttr('nonamespaceURI') , 1)
  1161. self.assertEquals( x._getAttr('NonenamespaceURI') , 2)
  1162. self.assertEquals( x._getAttr(('http://some/namespace',
  1163. 'namespaceURIattr1')) , 3)
  1164. self.assertEquals( x._getAttr(('http://some/other/namespace',
  1165. 'namespaceURIattr2')) , 4)
  1166. self.assertEquals( x._getAttr('non-extant attr') , None)
  1167. y = buildSOAP(x)
  1168. z = parseSOAPRPC(y)
  1169. self.assertEquals( z , 1)
  1170. #### decimal
  1171. # First some things that shouldn't be valid
  1172. test = ('hello', (), [], {})
  1173. t = decimalType
  1174. for i in test:
  1175. try:
  1176. t(i)
  1177. raise AssertionError, \
  1178. "instantiated a %s with a bad type (%s)" % \
  1179. (t.__name__, repr(type(i)))
  1180. except AssertionError:
  1181. raise
  1182. except:
  1183. pass
  1184. # Now some things that should
  1185. for i in (10, 3.14, 23L):
  1186. x = t(i)
  1187. d = x._marshalData()
  1188. if d != str(i):
  1189. raise AssertionError, "expected %f, got %s" % (i, d)
  1190. y = buildSOAP(x)
  1191. z = parseSOAPRPC(y)
  1192. if z != i:
  1193. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  1194. # Now test parsing, both valid and invalid
  1195. test = (('hello', None), ('1.2.3', None), ('10', 10), ('10.', 10),
  1196. ('.1', .1), ('.1000000', .1), (ws + '10.4' + ws, 10.4))
  1197. for i in test:
  1198. try:
  1199. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  1200. if z != i[1]:
  1201. raise AssertionError, "%s: expected %s, got %s" % \
  1202. (i[0], i[1], repr(z))
  1203. except AssertionError:
  1204. raise
  1205. except:
  1206. if i[1] != None:
  1207. raise AssertionError, \
  1208. "parsing %s as %s threw exception %s:%s" % \
  1209. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  1210. #### float
  1211. # First some things that shouldn't be valid
  1212. test = ('hello', (), [], {}, -3.402823466391E+38, 3.402823466391E+38)
  1213. t = floatType
  1214. for i in test:
  1215. try:
  1216. t(i)
  1217. raise AssertionError, \
  1218. "instantiated a %s with a bad value (%s)" % \
  1219. (t.__name__, repr(i))
  1220. except AssertionError:
  1221. raise
  1222. except ValueError:
  1223. pass
  1224. # Now some things that should
  1225. for i in (10, 3.14, 23L, -3.4028234663852886E+38, 3.4028234663852886E+38):
  1226. x = t(i)
  1227. d = x._marshalData()
  1228. if not nearlyeq(float(d), i):
  1229. raise AssertionError, "expected %f, got %s" % (i, d)
  1230. y = buildSOAP(x)
  1231. z = parseSOAPRPC(y)
  1232. if not nearlyeq(z, i):
  1233. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  1234. # Now test parsing, both valid and invalid
  1235. test = (('hello', None), ('1.2.3', None), ('10', 10), ('10.', 10),
  1236. ('.1', .1), ('.1000000', .1), (ws + '10.4' + ws, 10.4),
  1237. ('-3.402823466391E+38', None), ('3.402823466391E+38', None),
  1238. ('-3.4028234663852886E+38', -3.4028234663852886E+38),
  1239. ('3.4028234663852886E+38', 3.4028234663852886E+38))
  1240. for i in test:
  1241. try:
  1242. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  1243. if abs(z - i[1]) > 1e-6:
  1244. raise AssertionError, "%s: expected %s, got %s" % \
  1245. (i[0], i[1], repr(z))
  1246. except AssertionError:
  1247. raise
  1248. except:
  1249. if i[1] != None:
  1250. raise AssertionError, \
  1251. "parsing %s as %s threw exception %s:%s" % \
  1252. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  1253. #### double
  1254. # First some things that shouldn't be valid
  1255. test = ('hello', (), [], {},
  1256. -1.7976931348623159E+308, 1.7976931348623159E+308)
  1257. t = doubleType
  1258. for i in test:
  1259. try:
  1260. t(i)
  1261. # Hide this error for now, cause it is a bug in python 2.0 and 2.1
  1262. if not (sys.version_info[0] == 2 and sys.version_info[1] <= 2
  1263. and i==1.7976931348623159E+308):
  1264. raise AssertionError, \
  1265. "instantiated a double with a bad value (%s)" % repr(i)
  1266. except AssertionError:
  1267. raise
  1268. except ValueError:
  1269. pass
  1270. # Now some things that should
  1271. for i in (10, 3.14, 23L, -1.79769313486E+308, 1.79769313486E+308):
  1272. x = t(i)
  1273. d = x._marshalData()
  1274. if not nearlyeq(float(d), i):
  1275. raise AssertionError, "expected %s, got %s" % (i, str(x))
  1276. y = buildSOAP(x)
  1277. z = parseSOAPRPC(y)
  1278. if not nearlyeq(z, i):
  1279. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  1280. # Now test parsing, both valid and invalid
  1281. test = (('hello', None), ('1.2.3', None), ('10', 10), ('10.', 10),
  1282. ('.1', .1), ('.1000000', .1), (ws + '10.4' + ws, 10.4),
  1283. ('-1.7976931348623159E+308', None), ('1.7976931348623158E+308', None),
  1284. ('-1.79769313486E+308', -1.79769313486E+308),
  1285. ('1.79769313486E+308', 1.79769313486E+308))
  1286. for i in test:
  1287. try:
  1288. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  1289. if abs(z - i[1]) > 1e-6:
  1290. raise AssertionError, "%s: expected %s, got %s" % \
  1291. (i[0], i[1], repr(z))
  1292. except AssertionError:
  1293. raise
  1294. except:
  1295. if i[1] != None:
  1296. raise AssertionError, \
  1297. "parsing %s as %s threw exception %s:%s" % \
  1298. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  1299. #### hexBinary
  1300. x = ''
  1301. for i in range(256):
  1302. x += chr(i)
  1303. test = ('', x, 'hello')
  1304. t = hexBinaryType
  1305. l = []
  1306. for i in test:
  1307. l.append(hexBinaryType(i))
  1308. x = buildSOAP(l)
  1309. y = parseSOAPRPC(x)
  1310. for i in range(len(test)):
  1311. if test[i] != y[i]:
  1312. raise AssertionError, "@ %d expected '%s', got '%s'" % \
  1313. (i, test[i], y[i])
  1314. # Now test parsing, both valid and invalid
  1315. test = (('hello', None), ('6163 747A65726F', None), ('6163747A65726', None),
  1316. ('6163747A65726F', 'actzero'), (ws + '6163747A65726F' + ws, 'actzero'))
  1317. for i in test:
  1318. try:
  1319. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  1320. if z != i[1]:
  1321. raise AssertionError, "%s: expected %s, got %s" % \
  1322. (i[0], i[1], repr(z))
  1323. except AssertionError:
  1324. raise
  1325. except:
  1326. if i[1] != None:
  1327. raise AssertionError, \
  1328. "parsing %s as %s threw exception %s:%s" % \
  1329. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  1330. #### base64Binary and base64
  1331. s = ''
  1332. for i in range(256):
  1333. s += chr(i)
  1334. for t in (base64BinaryType, base64Type):
  1335. # First some things that shouldn't be valid
  1336. test = ((), [], {}, lambda x: x)
  1337. for i in test:
  1338. try:
  1339. t(i)
  1340. raise AssertionError, \
  1341. "instantiated a %s with a bad value (%s)" % \
  1342. (t.__name__, repr(i))
  1343. except AssertionError:
  1344. raise
  1345. except AttributeError:
  1346. pass
  1347. # Now some things that should
  1348. test = ('', s, u'hello')
  1349. l = []
  1350. for i in test:
  1351. l.append(t(i))
  1352. x = buildSOAP(l)
  1353. y = parseSOAPRPC(x)
  1354. for i in range(len(test)):
  1355. if test[i] != y[i]:
  1356. raise AssertionError, "@ %d expected '%s', got '%s'" % \
  1357. (i, test[i], y[i])
  1358. # Now test parsing, both valid and invalid
  1359. test = (('hello', None), ('YWN0emVybw=', None),
  1360. ('YWN 0emVybw==', 'actzero'), ('YWN0emVybw==', 'actzero'),
  1361. (ws + 'YWN0emVybw==' + ws, 'actzero'))
  1362. for i in test:
  1363. try:
  1364. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  1365. if z != i[1]:
  1366. raise AssertionError, "%s: expected %s, got %s" % \
  1367. (i[0], i[1], repr(z))
  1368. except AssertionError:
  1369. raise
  1370. except:
  1371. if i[1] != None:
  1372. raise AssertionError, \
  1373. "parsing %s as %s threw exception %s:%s" % \
  1374. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  1375. #### binary (uses s from above)
  1376. # First some check invalid encodings
  1377. try:
  1378. x = binaryType('hello', encoding = 'yellow')
  1379. raise AssertionError, "created binary with invalid encoding"
  1380. except AssertionError:
  1381. raise
  1382. except:
  1383. pass
  1384. for t in ('hex', 'base64'):
  1385. # First some things that shouldn't be valid
  1386. test = ((), [], {}, lambda x: x)
  1387. for i in test:
  1388. try:
  1389. binaryType(i, encoding = t)
  1390. raise AssertionError, \
  1391. "instantiated a %s binary with a bad value (%s)" % \
  1392. (e, repr(i))
  1393. except AssertionError:
  1394. raise
  1395. except AttributeError:
  1396. pass
  1397. # Now some things that should
  1398. test = ('', s, u'hello')
  1399. l = []
  1400. for i in test:
  1401. l.append(binaryType(i, encoding = t))
  1402. x = buildSOAP(l)
  1403. y = parseSOAPRPC(x)
  1404. for i in range(len(test)):
  1405. if test[i] != y[i]:
  1406. raise AssertionError, "@ %d expected '%s', got '%s'" % \
  1407. (i, test[i], y[i])
  1408. # Now test parsing, both valid and invalid
  1409. if t == 'hex':
  1410. test = (('hello', None), ('6163 747A65726F', None),
  1411. ('6163747A65726', None), ('6163747A65726F', 'actzero'),
  1412. (ws + '6163747A65726F' + ws, 'actzero'))
  1413. else:
  1414. test = (('hello', None), ('YWN0emVybw=', None),
  1415. ('YWN 0emVybw==', 'actzero'), ('YWN0emVybw==', 'actzero'),
  1416. (ws + 'YWN0emVybw==' + ws, 'actzero'))
  1417. for i in test:
  1418. try:
  1419. z = parseSOAPRPC(self.build_xml(NS.XSD, 'binary', i[0],
  1420. ' encoding="%s"' % t))
  1421. if z != i[1]:
  1422. raise AssertionError, "%s: expected %s, got %s" % \
  1423. (i[0], i[1], repr(z))
  1424. except AssertionError:
  1425. raise
  1426. except:
  1427. if i[1] != None:
  1428. raise AssertionError, \
  1429. "parsing %s as %s threw exception %s:%s" % \
  1430. (i[0], t, sys.exc_info()[0], sys.exc_info()[1])
  1431. # Finally try an Array of binaries (with references!)
  1432. test = ('', s, u'hello')
  1433. l = []
  1434. for i in test:
  1435. l.append(binaryType(i, encoding = t))
  1436. l.append(l[1])
  1437. x = buildSOAP(l)
  1438. y = parseSOAPRPC(x)
  1439. for i in range(len(test)):
  1440. if test[i] != y[i]:
  1441. raise AssertionError, "@ %d expected '%s', got '%s'" % \
  1442. (i, test[i], y[i])
  1443. # Make sure the references worked
  1444. self.assertEquals( id(y[1]) , id(y[3]))
  1445. def badTest(self, t, data):
  1446. for i in data:
  1447. try:
  1448. t(i)
  1449. raise AssertionError, \
  1450. "instantiated a %s with a bad value (%s)" % \
  1451. (t.__name__, repr(i))
  1452. except AssertionError:
  1453. raise
  1454. except:
  1455. pass
  1456. def goodTest(self, t, data):
  1457. for i in data:
  1458. x = t(i[0])
  1459. d = x._marshalData()
  1460. if d != i[1]:
  1461. raise AssertionError, "%s(%s): expected %s, got %s" % \
  1462. (t.__name__, repr(i[0]), i[1], d)
  1463. y = buildSOAP(x)
  1464. z = parseSOAPRPC(y)
  1465. if z != i[2]:
  1466. raise AssertionError, "%s(%s): expected %s, got %s" % \
  1467. (t.__name__, repr(i[0]), repr(i[2]), repr(z))
  1468. def parseTest(self, t, data):
  1469. for i in data:
  1470. try:
  1471. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4],
  1472. i[0]))
  1473. if z != i[1]:
  1474. raise AssertionError, "%s(%s): expected %s, got %s" % \
  1475. (t.__name__, repr(i[0]), i[1], repr(z))
  1476. except AssertionError:
  1477. raise
  1478. except:
  1479. if i[1] != N:
  1480. raise AssertionError, \
  1481. "parsing %s as %s threw exception %s:%s" % \
  1482. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  1483. def allTests(self, t, baddata, gooddata, parsedata):
  1484. self.badTest(t, baddata)
  1485. self.goodTest(t, gooddata)
  1486. self.parseTest(t, parsedata)
  1487. # duration and timeDuration
  1488. def testTimeDuration(self):
  1489. baddata = \
  1490. (
  1491. 'hello',
  1492. ('hello',),
  1493. (-10, -10),
  1494. (-10, 0, -10),
  1495. (10.5, 10.5),
  1496. (0, 10.5, 0, 10.5, 0),
  1497. (1, 2, 3, 4, 5, 6, 7),
  1498. (1, 2, 'hello', 4, 5, 6),
  1499. (1, 2, 3.5, 4, 5, 6),
  1500. )
  1501. gooddata = \
  1502. (
  1503. (0, 'PT0S', (N, N, N, N, N, 0.0,)),
  1504. ((), 'PT0S', (N, N, N, N, N, 0.0,)),
  1505. ([], 'PT0S', (N, N, N, N, N, 0.0,)),
  1506. ((0.5,), 'PT0.5S', (N, N, N, N, N, 0.5,)),
  1507. (10L, 'PT10S', (N, N, N, N, N, 10.0,)),
  1508. (-10, '-PT10S', (N, N, N, N, N, -10.0,)),
  1509. (10.5, 'PT10.5S', (N, N, N, N, N, 10.5,)),
  1510. ((10L, 20), 'PT10M20S', (N, N, N, N, 10, 20.0)),
  1511. ((-10, 20), '-PT10M20S', (N, N, N, N, -10, 20.0)),
  1512. ((10, 0), 'PT10M', (N, N, N, N, 10, N)),
  1513. ((10, 0, 0), 'PT10H', (N, N, N, 10, N, N)),
  1514. ((10, 0L, 0, 0), 'P10D', (N, N, 10, N, N, N)),
  1515. ((10, 0, 0, 0, 0), 'P10M', (N, 10, N, N, N, N)),
  1516. ((10, 0, 0, 0L, 0, 0), 'P10Y', (10, N, N, N, N, N)),
  1517. ((-10, 0, 0, 0, 0, 0), '-P10Y', (-10, N, N, N, N, N)),
  1518. ((10, 0, 0, 0, 0, 20L), 'P10YT20S', (10, N, N, N, N, 20.0,)),
  1519. ((1, 2, 3, 4, 5, 6.75), 'P1Y2M3DT4H5M6.75S',
  1520. (1, 2, 3, 4, 5, 6.75)),
  1521. ((-1, 2, 3, 4, 5, 6.75), '-P1Y2M3DT4H5M6.75S',
  1522. (-1, 2, 3, 4, 5, 6.75)),
  1523. ((1, 2, 3, 10, 30, 0), 'P1Y2M3DT10H30M',
  1524. (1, 2, 3, 10, 30, N)),
  1525. ((1e6, 2e6, 3e6, 4e6, 5e6, 6.7e6),
  1526. 'P1000000Y2000000M3000000DT4000000H5000000M6700000S',
  1527. (1e6, 2e6, 3e6, 4e6, 5e6, 6.7e6)),
  1528. ((1347, 0, N, 0, 0), 'P1347M', (N, 1347, N, N, N, N)),
  1529. ((-1347, 0, 0, 0, N), '-P1347M', (N, -1347, N, N, N, N)),
  1530. ((1e15, 0, 0, 0, 0), 'P1000000000000000M',
  1531. (N, 1000000000000000L, N, N, N, N)),
  1532. ((-1e15, 0, 0, 0, 0), '-P1000000000000000M',
  1533. (N, -1000000000000000L, N, N, N, N)),
  1534. ((1000000000000000L, 0, 0, 0, 0), 'P1000000000000000M',
  1535. (N, 1000000000000000L, N, N, N, N)),
  1536. ((-1000000000000000L, 0, 0, 0, 0), '-P1000000000000000M',
  1537. (N, -1000000000000000L, N, N, N, N)),
  1538. )
  1539. parsedata = (
  1540. ('hello', N),
  1541. ('P T0S', N),
  1542. ('P10.5Y10.5M', N),
  1543. ('P1Y2MT', N),
  1544. ('PT0S', (N, N, N, N, N, 0,)),
  1545. ('P10Y', (10, N, N, N, N, N)),
  1546. (ws + 'P10M' + ws, (N, 10, N, N, N, N)),
  1547. ('P0Y1347M', (0, 1347, N, N, N, N)),
  1548. ('P0Y1347M0D', (0, 1347, 0, N, N, N)),
  1549. ('P0MT0M', (N, 0, N, N, 0, N)),
  1550. )
  1551. for t in (durationType, timeDurationType):
  1552. self.allTests(t, baddata, gooddata, parsedata)
  1553. # dateTime, timeInstant, and timePeriod
  1554. def testTimePeriod(self):
  1555. baddata = \
  1556. (
  1557. 'hello',
  1558. ('hello',),
  1559. (1, 2, 3, 4, 5),
  1560. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  1561. (1, 2, 3, 4, 5, 'hello'),
  1562. (1, 2.5, 3, 4, 5, 6),
  1563. (1, 0, 3, 4, 5, 6),
  1564. (1, 13, 3, 4, 5, 6),
  1565. (1, 1, 0, 4, 5, 6),
  1566. (1, 1, 32, 4, 5, 6),
  1567. (1, 2, 29, 4, 5, 6),
  1568. (0, 2, 30, 4, 5, 6),
  1569. (100, 2, 29, 4, 5, 6),
  1570. (1, 2, 3, -1, 5, 6),
  1571. (1, 2, 3, 24, 5, 6),
  1572. (1, 2, 3, 4, -1, 6),
  1573. (1, 2, 3, 4, 60, 6),
  1574. (1, 2, 3, 4, 5, -1),
  1575. (1, 2, 3, 4, 5, 61),
  1576. (1, 3, 32, 4, 5, 6),
  1577. (1, 4, 31, 4, 5, 6),
  1578. (1, 5, 32, 4, 5, 6),
  1579. (1, 6, 31, 4, 5, 6),
  1580. (1, 7, 32, 4, 5, 6),
  1581. (1, 8, 32, 4, 5, 6),
  1582. (1, 9, 31, 4, 5, 6),
  1583. (1, 10, 32, 4, 5, 6),
  1584. (1, 11, 31, 4, 5, 6),
  1585. (1, 12, 32, 4, 5, 6),
  1586. )
  1587. gooddata = \
  1588. (
  1589. (1L, '1970-01-01T00:00:01Z', (1970, 1, 1, 0, 0, 1.0)),
  1590. (1.5, '1970-01-01T00:00:01.5Z', (1970, 1, 1, 0, 0, 1.5)),
  1591. ((-1, 2, 3, 4, 5, 6), '-0001-02-03T04:05:06Z',
  1592. (-1, 2, 3, 4, 5, 6.0)),
  1593. ((1, 2, 3, 4, 5, 6), '0001-02-03T04:05:06Z',
  1594. (1, 2, 3, 4, 5, 6.0)),
  1595. ((10, 2, 3, 4, 5, 6), '0010-02-03T04:05:06Z',
  1596. (10, 2, 3, 4, 5, 6.0)),
  1597. ((100, 2, 3, 4, 5, 6), '0100-02-03T04:05:06Z',
  1598. (100, 2, 3, 4, 5, 6.0)),
  1599. ((1970, 2, 3, 4, 5, 6), '1970-02-03T04:05:06Z',
  1600. (1970, 2, 3, 4, 5, 6.0)),
  1601. ((-1970, 2, 3, 4, 5, 6), '-1970-02-03T04:05:06Z',
  1602. (-1970, 2, 3, 4, 5, 6.0)),
  1603. ((1970L, 2.0, 3.0, 4L, 5L, 6.875), '1970-02-03T04:05:06.875Z',
  1604. (1970, 2, 3, 4, 5, 6.875)),
  1605. ((11990, 1, 2, 3, 4L, 5.25, 0, 0, 0),
  1606. '11990-01-02T03:04:05.25Z',
  1607. (11990, 1, 2, 3, 4, 5.25)),
  1608. ((1e15, 1, 2, 3, 4L, 5.25, 0, 0, 0),
  1609. '1000000000000000-01-02T03:04:05.25Z',
  1610. (1e15, 1, 2, 3, 4, 5.25)),
  1611. ((-1e15, 1, 2, 3, 4L, 5.25, 0, 0, 0),
  1612. '-1000000000000000-01-02T03:04:05.25Z',
  1613. (-1e15, 1, 2, 3, 4, 5.25)),
  1614. ((1000000000000000L, 1, 2, 3, 4L, 5.25, 0, 0, 0),
  1615. '1000000000000000-01-02T03:04:05.25Z',
  1616. (1e15, 1, 2, 3, 4, 5.25)),
  1617. ((-1000000000000000L, 1, 2, 3, 4L, 5.25, 0, 0, 0),
  1618. '-1000000000000000-01-02T03:04:05.25Z',
  1619. (-1e15, 1, 2, 3, 4, 5.25)),
  1620. )
  1621. parsedata = \
  1622. (
  1623. # Some strings that won't match the r.e.
  1624. ('hello', N),
  1625. ('1970 -01 -01T00:00:01Z', N),
  1626. ('0001-02-03t07:08:23Z', N),
  1627. # Invalid ranges
  1628. ('2001-00-03T07:08:23Z', N),
  1629. ('2001-13-03T07:08:23Z', N),
  1630. ('2001-02-00T07:08:23Z', N),
  1631. ('2001-02-29T07:08:23Z', N),
  1632. ('2000-02-30T07:08:23Z', N),
  1633. ('1900-02-29T07:08:23Z', N),
  1634. ('2001-02-03T24:08:23Z', N),
  1635. ('2001-02-03T04:60:23Z', N),
  1636. ('2001-02-03T04:05:61Z', N),
  1637. ('2001-01-32T04:05:06Z', N),
  1638. ('2001-03-32T04:05:06Z', N),
  1639. ('2001-04-31T04:05:06Z', N),
  1640. ('2001-05-32T04:05:06Z', N),
  1641. ('2001-06-31T04:05:06Z', N),
  1642. ('2001-07-32T04:05:06Z', N),
  1643. ('2001-08-32T04:05:06Z', N),
  1644. ('2001-09-31T04:05:06Z', N),
  1645. ('2001-10-32T04:05:06Z', N),
  1646. ('2001-11-31T04:05:06Z', N),
  1647. ('2001-12-32T04:05:06Z', N),
  1648. # Whitespace
  1649. (ws + '1970-01-01T00:00:00Z' + ws, (1970, 1, 1, 0, 0, 0)),
  1650. # No timezones
  1651. ('11971-02-03T04:05:06.125', (11971, 2, 3, 4, 5, 6.125)),
  1652. ('1971-02-03T04:05:06.125', (1971, 2, 3, 4, 5, 6.125)),
  1653. ('-1971-02-03T04:05:06.125', (-1971, 2, 3, 4, 5, 6.125)),
  1654. # Non-zulu
  1655. ('11971-02-03T04:05:06.125-07:08', (11971, 2, 3, 11, 13, 6.125)),
  1656. ('11971-02-03T04:05:06.125+07:08', (11971, 2, 2, 20, 57, 6.125)),
  1657. ('-11971-02-03T04:05:06.125-07:08', (-11971, 2, 3, 11, 13, 6.125)),
  1658. ('-11971-02-03T04:05:06.125+07:08', (-11971, 2, 2, 20, 57, 6.125)),
  1659. ('1971-02-03T04:05:06.125-07:08', (1971, 2, 3, 11, 13, 6.125)),
  1660. ('1971-02-03T04:05:06.125+07:08', (1971, 2, 2, 20, 57, 6.125)),
  1661. ('-1971-02-03T04:05:06.125-07:08', (-1971, 2, 3, 11, 13, 6.125)),
  1662. ('-1971-02-03T04:05:06.125+07:08', (-1971, 2, 2, 20, 57, 6.125)),
  1663. # Edgepoints (ranges)
  1664. ('2001-01-03T07:08:09Z', (2001, 1, 3, 7, 8, 9)),
  1665. ('2001-12-03T07:08:09Z', (2001, 12, 3, 7, 8, 9)),
  1666. ('2001-02-01T07:08:09Z', (2001, 2, 1, 7, 8, 9)),
  1667. ('2001-02-28T07:08:09Z', (2001, 2, 28, 7, 8, 9)),
  1668. ('2000-02-29T07:08:09Z', (2000, 2, 29, 7, 8, 9)),
  1669. ('1900-02-28T07:08:09Z', (1900, 2, 28, 7, 8, 9)),
  1670. ('2001-02-03T00:08:09Z', (2001, 2, 3, 0, 8, 9)),
  1671. ('2001-02-03T23:08:09Z', (2001, 2, 3, 23, 8, 9)),
  1672. ('2001-02-03T04:00:09Z', (2001, 2, 3, 4, 0, 9)),
  1673. ('2001-02-03T04:59:09Z', (2001, 2, 3, 4, 59, 9)),
  1674. ('2001-02-03T04:05:00Z', (2001, 2, 3, 4, 5, 0)),
  1675. ('2001-02-03T04:05:60.9Z', (2001, 2, 3, 4, 5, 60.9)),
  1676. ('2001-01-31T04:05:06Z', (2001, 1, 31, 4, 5, 6)),
  1677. ('2001-03-31T04:05:06Z', (2001, 3, 31, 4, 5, 6)),
  1678. ('2001-04-30T04:05:06Z', (2001, 4, 30, 4, 5, 6)),
  1679. ('2001-05-31T04:05:06Z', (2001, 5, 31, 4, 5, 6)),
  1680. ('2001-06-30T04:05:06Z', (2001, 6, 30, 4, 5, 6)),
  1681. ('2001-07-31T04:05:06Z', (2001, 7, 31, 4, 5, 6)),
  1682. ('2001-08-31T04:05:06Z', (2001, 8, 31, 4, 5, 6)),
  1683. ('2001-09-30T04:05:06Z', (2001, 9, 30, 4, 5, 6)),
  1684. ('2001-10-31T04:05:06Z', (2001, 10, 31, 4, 5, 6)),
  1685. ('2001-11-30T04:05:06Z', (2001, 11, 30, 4, 5, 6)),
  1686. ('2001-12-31T04:05:06Z', (2001, 12, 31, 4, 5, 6)),
  1687. # Edgepoints (crossing boundaries)
  1688. ('0001-01-01T07:08:23+07:08', (1, 1, 1, 0, 0, 23)),
  1689. ('0001-01-01T07:07:42+07:08', (0, 12, 31, 23, 59, 42)),
  1690. ('-0004-01-01T07:07:42+07:08', (-5, 12, 31, 23, 59, 42)),
  1691. ('2001-03-01T07:07:42+07:08', (2001, 2, 28, 23, 59, 42)),
  1692. ('2000-03-01T07:07:42+07:08', (2000, 2, 29, 23, 59, 42)),
  1693. ('1900-03-01T07:07:42+07:08', (1900, 2, 28, 23, 59, 42)),
  1694. )
  1695. for t in (dateTimeType, timeInstantType, timePeriodType):
  1696. self.allTests(t, baddata, gooddata, parsedata)
  1697. # recurringInstant
  1698. def testRecurringInstant(self):
  1699. baddata = \
  1700. (
  1701. 'hello',
  1702. ('hello',),
  1703. (1, 2, N, 3, 4, 5),
  1704. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  1705. (1, 2, 3, 4, 5, 'hello'),
  1706. (1, 2, 3.5, 4, 5, 6),
  1707. )
  1708. gooddata = \
  1709. (
  1710. (1L, '1970-01-01T00:00:01Z', (1970, 1, 1, 0, 0, 1.0)),
  1711. (1.5, '1970-01-01T00:00:01.5Z', (1970, 1, 1, 0, 0, 1.5)),
  1712. (1e9, '2001-09-09T01:46:40Z', (2001, 9, 9, 1, 46, 40.0)),
  1713. ((1, 1, 2, 3, 4, 5), '-01-01-02T03:04:05Z',
  1714. (1, 1, 2, 3, 4, 5)),
  1715. ((-1, 1, 2, 3, 4, 5), '--01-01-02T03:04:05Z',
  1716. (-1, 1, 2, 3, 4, 5)),
  1717. ((10, 1, 2, 3, 4, 5), '-10-01-02T03:04:05Z',
  1718. (10, 1, 2, 3, 4, 5)),
  1719. ((-10, 1, 2, 3, 4, 5), '--10-01-02T03:04:05Z',
  1720. (-10, 1, 2, 3, 4, 5)),
  1721. ((100, 1, 2, 3, 4, 5), '0100-01-02T03:04:05Z',
  1722. (100, 1, 2, 3, 4, 5)),
  1723. ((-100, 1, 2, 3, 4, 5), '-0100-01-02T03:04:05Z',
  1724. (-100, 1, 2, 3, 4, 5)),
  1725. ((1970L, 1, 2, 3, 4, 5), '1970-01-02T03:04:05Z',
  1726. (1970, 1, 2, 3, 4, 5)),
  1727. ((1970L, 1, 2L, 3, 4.0, 5.25), '1970-01-02T03:04:05.25Z',
  1728. (1970, 1, 2, 3, 4, 5.25)),
  1729. ((11990, 1, 2, 3L, 4, 5.25), '11990-01-02T03:04:05.25Z',
  1730. (11990, 1, 2, 3, 4, 5.25)),
  1731. ((1e15, 1, 2, 3L, 4, 5.25),
  1732. '1000000000000000-01-02T03:04:05.25Z',
  1733. (1e15, 1, 2, 3, 4, 5.25)),
  1734. ((-1e15, 1, 2, 3L, 4, 5.25),
  1735. '-1000000000000000-01-02T03:04:05.25Z',
  1736. (-1e15, 1, 2, 3, 4, 5.25)),
  1737. ((N, 1, 2, 3, 4L, 5.25), '---01-02T03:04:05.25Z',
  1738. (N, 1, 2, 3, 4, 5.25)),
  1739. ((N, N, 2, 3, 4, 5.25, 0, 0, 0), '-----02T03:04:05.25Z',
  1740. (N, N, 2, 3, 4, 5.25)),
  1741. ((N, N, -2, 3, 4, 5.25, 0, 0, 0), '------02T03:04:05.25Z',
  1742. (N, N, -2, 3, 4, 5.25)),
  1743. ((N, N, N, 3, 4, 5.25), '------T03:04:05.25Z',
  1744. (N, N, N, 3, 4, 5.25)),
  1745. ((N, N, N, N, 4, 5.25, 0, 0, 0), '------T-:04:05.25Z',
  1746. (N, N, N, N, 4, 5.25)),
  1747. ((N, N, N, N, N, 5.25), '------T-:-:05.25Z',
  1748. (N, N, N, N, N, 5.25)),
  1749. ((N, N, N, N, N, -5.25), '-------T-:-:05.25Z',
  1750. (N, N, N, N, N, -5.25)),
  1751. ((N, N, N, N, N, N, 0, 0, 0), '------T-:-:-Z',
  1752. (N, N, N, N, N, N)),
  1753. ((N, N, N, N, N, N, N), '------T-:-:-Z',
  1754. (N, N, N, N, N, N)),
  1755. ((N, N, N, N, N, N, N, N),
  1756. '------T-:-:-Z', (N, N, N, N, N, N)),
  1757. ((N, N, N, N, N, N, N, N, N),
  1758. '------T-:-:-Z', (N, N, N, N, N, N)),
  1759. )
  1760. parsedata = \
  1761. (
  1762. # Some strings that won't match the r.e.
  1763. ('hello', N),
  1764. ('1970 -01 -01T00:00:01Z', N),
  1765. ('0001-01-01t07:08:23+07:08', N),
  1766. # Invalid ranges
  1767. ('2001-00-03T07:08:23Z', N),
  1768. ('2001-13-03T07:08:23Z', N),
  1769. ('2001-02-00T07:08:23Z', N),
  1770. ('2001-02-29T07:08:23Z', N),
  1771. ('2000-02-30T07:08:23Z', N),
  1772. ('1900-02-29T07:08:23Z', N),
  1773. ('2001-02-03T24:08:23Z', N),
  1774. ('2001-02-03T04:60:23Z', N),
  1775. ('2001-02-03T04:05:61Z', N),
  1776. ('2001-01-32T04:05:06Z', N),
  1777. ('2001-03-32T04:05:06Z', N),
  1778. ('2001-04-31T04:05:06Z', N),
  1779. ('2001-05-32T04:05:06Z', N),
  1780. ('2001-06-31T04:05:06Z', N),
  1781. ('2001-07-32T04:05:06Z', N),
  1782. ('2001-08-32T04:05:06Z', N),
  1783. ('2001-09-31T04:05:06Z', N),
  1784. ('2001-10-32T04:05:06Z', N),
  1785. ('2001-11-31T04:05:06Z', N),
  1786. ('2001-12-32T04:05:06Z', N),
  1787. # Whitespace
  1788. (ws + '1970-01-01T00:00:01Z' + ws, (1970, 1, 1, 0, 0, 1)),
  1789. # No timezones
  1790. ('11971-02-03T04:05:06.125', (11971, 2, 3, 4, 5, 6.125)),
  1791. ('-11971-02-03T04:05:06.125', (-11971, 2, 3, 4, 5, 6.125)),
  1792. ('1971-02-03T04:05:06.125', (1971, 2, 3, 4, 5, 6.125)),
  1793. ('-1971-02-03T04:05:06.125', (-1971, 2, 3, 4, 5, 6.125)),
  1794. ('-71-02-03T04:05:06.125', (71, 2, 3, 4, 5, 6.125)),
  1795. ('--71-02-03T04:05:06.125', (-71, 2, 3, 4, 5, 6.125)),
  1796. ('---02-03T04:05:06.125', (N, 2, 3, 4, 5, 6.125)),
  1797. ('----02-03T04:05:06.125', (N, -2, 3, 4, 5, 6.125)),
  1798. ('-----03T04:05:06.125', (N, N, 3, 4, 5, 6.125)),
  1799. ('------03T04:05:06.125', (N, N, -3, 4, 5, 6.125)),
  1800. ('------T04:05:06.125', (N, N, N, 4, 5, 6.125)),
  1801. ('-------T04:05:06.125', (N, N, N, -4, 5, 6.125)),
  1802. ('------T-:05:06.125', (N, N, N, N, 5, 6.125)),
  1803. ('-------T-:05:06.125', (N, N, N, N, -5, 6.125)),
  1804. ('------T-:-:06.125', (N, N, N, N, N, 6.125)),
  1805. ('-------T-:-:06.125', (N, N, N, N, N, -6.125)),
  1806. ('------T-:-:-', (N, N, N, N, N, N)),
  1807. ('-------T-:-:-', (N, N, N, N, N, N)),
  1808. # Non-zulu
  1809. ('11971-02-03T04:05:06.125-07:08', (11971, 2, 3, 11, 13, 6.125)),
  1810. ('11971-02-03T04:05:06.125+07:08', (11971, 2, 2, 20, 57, 6.125)),
  1811. ('-11971-02-03T04:05:06.125-07:08', (-11971, 2, 3, 11, 13, 6.125)),
  1812. ('-11971-02-03T04:05:06.125+07:08', (-11971, 2, 2, 20, 57, 6.125)),
  1813. ('1971-02-03T04:05:06.125-07:08', (1971, 2, 3, 11, 13, 6.125)),
  1814. ('1971-02-03T04:05:06.125+07:08', (1971, 2, 2, 20, 57, 6.125)),
  1815. ('-1971-02-03T04:05:06.125-07:08', (-1971, 2, 3, 11, 13, 6.125)),
  1816. ('-1971-02-03T04:05:06.125+07:08', (-1971, 2, 2, 20, 57, 6.125)),
  1817. ('-71-02-03T04:05:06.125-07:08', (71, 2, 3, 11, 13, 6.125)),
  1818. ('-71-02-03T04:05:06.125+07:08', (71, 2, 2, 20, 57, 6.125)),
  1819. ('--71-02-03T04:05:06.125-07:08', (-71, 2, 3, 11, 13, 6.125)),
  1820. ('--71-02-03T04:05:06.125+07:08', (-71, 2, 2, 20, 57, 6.125)),
  1821. ('---02-03T04:05:06.125-07:08', (N, 2, 3, 11, 13, 6.125)),
  1822. ('---02-03T04:05:06.125+07:08', (N, 2, 2, 20, 57, 6.125)),
  1823. ('----02-03T04:05:06.125-07:08', (N, -2, 3, 11, 13, 6.125)),
  1824. ('----02-03T04:05:06.125+07:08', (N, -2, 2, 20, 57, 6.125)),
  1825. ('-----03T04:05:06.125-07:08', (N, N, 3, 11, 13, 6.125)),
  1826. ('-----03T04:05:06.125+07:08', (N, N, 2, 20, 57, 6.125)),
  1827. ('------03T04:05:06.125-07:08', (N, N, -3, 11, 13, 6.125)),
  1828. ('------03T04:05:06.125+07:08', (N, N, -4, 20, 57, 6.125)),
  1829. ('------T04:05:06.125-07:08', (N, N, N, 11, 13, 6.125)),
  1830. ('------T04:05:06.125+07:08', (N, N, N, -4, 57, 6.125)),
  1831. ('-------T04:05:06.125-07:08', (N, N, N, 3, 13, 6.125)),
  1832. ('-------T04:05:06.125+07:08', (N, N, N, -12, 57, 6.125)),
  1833. ('------T-:05:06.125-07:08', (N, N, N, N, 433, 6.125)),
  1834. ('------T-:05:06.125+07:08', (N, N, N, N, -423, 6.125)),
  1835. ('-------T-:05:06.125-07:08', (N, N, N, N, 423, 6.125)),
  1836. ('-------T-:05:06.125+07:08', (N, N, N, N, -433, 6.125)),
  1837. ('------T-:-:06.125-07:08', (N, N, N, N, 428, 6.125)),
  1838. ('------T-:-:06.125+07:08', (N, N, N, N, -428, 6.125)),
  1839. ('-------T-:-:06.125-07:08', (N, N, N, N, 427, 53.875)),
  1840. ('-------T-:-:06.125+07:08', (N, N, N, N, -429, 53.875)),
  1841. ('------T-:-:--07:08', (N, N, N, N, 428, 0)),
  1842. ('------T-:-:-+07:08', (N, N, N, N, -428, 0)),
  1843. ('-------T-:-:--07:08', (N, N, N, N, 428, 0)),
  1844. ('-------T-:-:-+07:08', (N, N, N, N, -428, 0)),
  1845. # Edgepoints (ranges)
  1846. ('2001-01-03T07:08:09Z', (2001, 1, 3, 7, 8, 9)),
  1847. ('2001-12-03T07:08:09Z', (2001, 12, 3, 7, 8, 9)),
  1848. ('2001-02-01T07:08:09Z', (2001, 2, 1, 7, 8, 9)),
  1849. ('2001-02-28T07:08:09Z', (2001, 2, 28, 7, 8, 9)),
  1850. ('2000-02-29T07:08:09Z', (2000, 2, 29, 7, 8, 9)),
  1851. ('1900-02-28T07:08:09Z', (1900, 2, 28, 7, 8, 9)),
  1852. ('2001-02-03T00:08:09Z', (2001, 2, 3, 0, 8, 9)),
  1853. ('2001-02-03T23:08:09Z', (2001, 2, 3, 23, 8, 9)),
  1854. ('2001-02-03T04:00:09Z', (2001, 2, 3, 4, 0, 9)),
  1855. ('2001-02-03T04:59:09Z', (2001, 2, 3, 4, 59, 9)),
  1856. ('2001-02-03T04:05:00Z', (2001, 2, 3, 4, 5, 0)),
  1857. ('2001-02-03T04:05:60.9Z', (2001, 2, 3, 4, 5, 60.9)),
  1858. ('2001-01-31T04:05:06Z', (2001, 1, 31, 4, 5, 6)),
  1859. ('2001-03-31T04:05:06Z', (2001, 3, 31, 4, 5, 6)),
  1860. ('2001-04-30T04:05:06Z', (2001, 4, 30, 4, 5, 6)),
  1861. ('2001-05-31T04:05:06Z', (2001, 5, 31, 4, 5, 6)),
  1862. ('2001-06-30T04:05:06Z', (2001, 6, 30, 4, 5, 6)),
  1863. ('2001-07-31T04:05:06Z', (2001, 7, 31, 4, 5, 6)),
  1864. ('2001-08-31T04:05:06Z', (2001, 8, 31, 4, 5, 6)),
  1865. ('2001-09-30T04:05:06Z', (2001, 9, 30, 4, 5, 6)),
  1866. ('2001-10-31T04:05:06Z', (2001, 10, 31, 4, 5, 6)),
  1867. ('2001-11-30T04:05:06Z', (2001, 11, 30, 4, 5, 6)),
  1868. ('2001-12-31T04:05:06Z', (2001, 12, 31, 4, 5, 6)),
  1869. # Edgepoints (crossing boundaries)
  1870. ('0001-01-01T07:08:23+07:08', (1, 1, 1, 0, 0, 23)),
  1871. ('0001-01-01T07:07:42+07:08', (0, 12, 31, 23, 59, 42)),
  1872. ('-0004-01-01T07:07:42+07:08', (-5, 12, 31, 23, 59, 42)),
  1873. ('2001-03-01T07:07:42+07:08', (2001, 2, 28, 23, 59, 42)),
  1874. ('2000-03-01T07:07:42+07:08', (2000, 2, 29, 23, 59, 42)),
  1875. ('1900-03-01T07:07:42+07:08', (1900, 2, 28, 23, 59, 42)),
  1876. ('---03-01T07:07:42+07:08', (N, 2, 28, 23, 59, 42)),
  1877. )
  1878. for t in (recurringInstantType,):
  1879. self.allTests(t, baddata, gooddata, parsedata)
  1880. def testTime(self):
  1881. baddata = \
  1882. (
  1883. 'hello',
  1884. ('hello',),
  1885. (1, 2, 3, 4, 5),
  1886. (1, 2, 3, 4, 5, 6, 7, 8),
  1887. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  1888. (1, 2, 'hello'),
  1889. (1, 2.5, 3),
  1890. (25, 0, 0),
  1891. (1, 60, 0),
  1892. (1, 0, 61),
  1893. )
  1894. gooddata = \
  1895. (
  1896. (1L, '00:00:01Z', (0, 0, 1.0)),
  1897. (1.5, '00:00:01.5Z', (0, 0, 1.5)),
  1898. (3661.5, '01:01:01.5Z', (1, 1, 1.5)),
  1899. (86399.75, '23:59:59.75Z', (23, 59, 59.75)),
  1900. ((1,), '01:00:00Z', (1, 0, 0)),
  1901. ((1, 2), '01:02:00Z', (1, 2, 0)),
  1902. ((10L, 20.0, 30), '10:20:30Z', (10, 20, 30.0)),
  1903. )
  1904. parsedata = \
  1905. (
  1906. # Some strings that won't match the r.e.
  1907. ('hello', N),
  1908. ('00 00:01Z', N),
  1909. ('07:O8:23Z', N),
  1910. # Invalid ranges
  1911. ('24:08:23Z', N),
  1912. ('04:60:23Z', N),
  1913. ('04:05:61Z', N),
  1914. # Whitespace
  1915. (ws + '00:00:01Z' + ws, (0, 0, 1)),
  1916. # No timezones
  1917. ('04:05:06.125', (4, 5, 6.125)),
  1918. # Non-zulu
  1919. ('04:05:06.125-07:08', (11, 13, 6.125)),
  1920. ('04:05:06.125+07:08', (-4, 57, 6.125)),
  1921. # Edgepoints (ranges)
  1922. ('00:08:09Z', (0, 8, 9)),
  1923. ('23:08:09Z', (23, 8, 9)),
  1924. ('04:00:09Z', (4, 0, 9)),
  1925. ('04:59:09Z', (4, 59, 9)),
  1926. ('04:05:00Z', (4, 5, 0)),
  1927. ('04:05:60.9Z', (4, 5, 60.9)),
  1928. # Edgepoints (crossing boundaries)
  1929. ('07:08:23+07:08', (0, 0, 23)),
  1930. ('07:07:42+07:08', (-1, 59, 42)),
  1931. )
  1932. for t in (timeType,):
  1933. self.allTests(t, baddata, gooddata, parsedata)
  1934. def testDate(self):
  1935. baddata = \
  1936. (
  1937. 'hello',
  1938. ('hello',),
  1939. (1, 2, 3, 4, 5),
  1940. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  1941. (1, 2, 3, 4, 5, 'hello'),
  1942. (1, 2.5, 3, 4, 5, 6),
  1943. (1, 2, 3.5),
  1944. (1, 0, 3),
  1945. (1, 13, 3),
  1946. (1, 1, 0),
  1947. (1, 1, 32),
  1948. (1, 2, 29),
  1949. (0, 2, 30),
  1950. (100, 2, 29),
  1951. (1, 3, 32),
  1952. (1, 4, 31),
  1953. (1, 5, 32),
  1954. (1, 6, 31),
  1955. (1, 7, 32),
  1956. (1, 8, 32),
  1957. (1, 9, 31),
  1958. (1, 10, 32),
  1959. (1, 11, 31),
  1960. (1, 12, 32),
  1961. )
  1962. gooddata = \
  1963. (
  1964. (1L, '1970-01-01Z', (1970, 1, 1)),
  1965. (1.5, '1970-01-01Z', (1970, 1, 1)),
  1966. ((2,), '0002-01-01Z', (2, 1, 1)),
  1967. ((2, 3), '0002-03-01Z', (2, 3, 1)),
  1968. ((-2, 3, 4), '-0002-03-04Z', (-2, 3, 4)),
  1969. ((2, 3, 4), '0002-03-04Z', (2, 3, 4)),
  1970. ((10, 2, 3), '0010-02-03Z', (10, 2, 3)),
  1971. ((100, 2, 3), '0100-02-03Z', (100, 2, 3)),
  1972. ((1970, 2, 3), '1970-02-03Z', (1970, 2, 3)),
  1973. ((-1970, 2, 3), '-1970-02-03Z', (-1970, 2, 3)),
  1974. ((1970L, 2.0, 3.0), '1970-02-03Z', (1970, 2, 3)),
  1975. ((11990, 1L, 2), '11990-01-02Z', (11990, 1, 2)),
  1976. ((1e15, 1, 2), '1000000000000000-01-02Z', (1e15, 1, 2)),
  1977. ((-1e15, 1, 2), '-1000000000000000-01-02Z', (-1e15, 1, 2)),
  1978. ((1000000000000000L, 1, 2), '1000000000000000-01-02Z',
  1979. (1e15, 1, 2)),
  1980. ((-1000000000000000L, 1, 2), '-1000000000000000-01-02Z',
  1981. (-1e15, 1, 2)),
  1982. )
  1983. parsedata = \
  1984. (
  1985. # Some strings that won't match the r.e.
  1986. ('hello', N),
  1987. ('1970 -01 -01Z', N),
  1988. ('0001-02-03z', N),
  1989. # Invalid ranges
  1990. ('2001-00-03Z', N),
  1991. ('2001-13-03Z', N),
  1992. ('2001-02-00Z', N),
  1993. ('2001-02-29Z', N),
  1994. ('2000-02-30Z', N),
  1995. ('1900-02-29Z', N),
  1996. ('2001-01-32Z', N),
  1997. ('2001-03-32Z', N),
  1998. ('2001-04-31Z', N),
  1999. ('2001-05-32Z', N),
  2000. ('2001-06-31Z', N),
  2001. ('2001-07-32Z', N),
  2002. ('2001-08-32Z', N),
  2003. ('2001-09-31Z', N),
  2004. ('2001-10-32Z', N),
  2005. ('2001-11-31Z', N),
  2006. ('2001-12-32Z', N),
  2007. # Whitespace
  2008. (ws + '1970-01-01Z' + ws, (1970, 1, 1)),
  2009. # No timezones
  2010. ('11971-02-03', (11971, 2, 3)),
  2011. ('1971-02-03', (1971, 2, 3)),
  2012. ('-1971-02-03', (-1971, 2, 3)),
  2013. # Non-zulu
  2014. ('11971-02-03-07:08', (11971, 2, 3)),
  2015. ('11971-02-03+07:08', (11971, 2, 2)),
  2016. ('-11971-02-03-07:08', (-11971, 2, 3)),
  2017. ('-11971-02-03+07:08', (-11971, 2, 2)),
  2018. ('1971-02-03-07:08', (1971, 2, 3)),
  2019. ('1971-02-03+07:08', (1971, 2, 2)),
  2020. ('-1971-02-03-07:08', (-1971, 2, 3)),
  2021. ('-1971-02-03+07:08', (-1971, 2, 2)),
  2022. # Edgepoints (ranges)
  2023. ('2001-01-03Z', (2001, 1, 3)),
  2024. ('2001-12-03Z', (2001, 12, 3)),
  2025. ('2001-02-01Z', (2001, 2, 1)),
  2026. ('2001-02-28Z', (2001, 2, 28)),
  2027. ('2000-02-29Z', (2000, 2, 29)),
  2028. ('1900-02-28Z', (1900, 2, 28)),
  2029. ('2001-01-31Z', (2001, 1, 31)),
  2030. ('2001-03-31Z', (2001, 3, 31)),
  2031. ('2001-04-30Z', (2001, 4, 30)),
  2032. ('2001-05-31Z', (2001, 5, 31)),
  2033. ('2001-06-30Z', (2001, 6, 30)),
  2034. ('2001-07-31Z', (2001, 7, 31)),
  2035. ('2001-08-31Z', (2001, 8, 31)),
  2036. ('2001-09-30Z', (2001, 9, 30)),
  2037. ('2001-10-31Z', (2001, 10, 31)),
  2038. ('2001-11-30Z', (2001, 11, 30)),
  2039. ('2001-12-31Z', (2001, 12, 31)),
  2040. # Edgepoints (crossing boundaries)
  2041. ('0001-01-01+07:08', (0, 12, 31)),
  2042. ('-0004-01-01+07:08', (-5, 12, 31)),
  2043. ('2001-03-01+07:08', (2001, 2, 28)),
  2044. ('2000-03-01+07:08', (2000, 2, 29)),
  2045. ('1900-03-01+07:08', (1900, 2, 28)),
  2046. )
  2047. for t in (dateType,):
  2048. self.allTests(t, baddata, gooddata, parsedata)
  2049. def testGYearMonth(self):
  2050. baddata = \
  2051. (
  2052. 'hello',
  2053. ('hello',),
  2054. (1, 2, 3),
  2055. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  2056. (1, 2, 3.5),
  2057. (1, 'hello'),
  2058. (1, 2.5),
  2059. (1, 0),
  2060. (1, 13),
  2061. )
  2062. gooddata = \
  2063. (
  2064. (1L, '1970-01Z', (1970, 1)),
  2065. (1.5, '1970-01Z', (1970, 1)),
  2066. ((2,), '0002-01Z', (2, 1)),
  2067. ((2, 3), '0002-03Z', (2, 3)),
  2068. ((-2, 3), '-0002-03Z', (-2, 3)),
  2069. ((10, 2), '0010-02Z', (10, 2)),
  2070. ((100, 2), '0100-02Z', (100, 2)),
  2071. ((1970, 2), '1970-02Z', (1970, 2)),
  2072. ((-1970, 2), '-1970-02Z', (-1970, 2)),
  2073. ((1970L, 2.0), '1970-02Z', (1970, 2)),
  2074. ((11990, 1L), '11990-01Z', (11990, 1)),
  2075. ((1e15, 1), '1000000000000000-01Z', (1e15, 1)),
  2076. ((-1e15, 1), '-1000000000000000-01Z', (-1e15, 1)),
  2077. ((1000000000000000L, 1), '1000000000000000-01Z', (1e15, 1)),
  2078. ((-1000000000000000L, 1), '-1000000000000000-01Z', (-1e15, 1)),
  2079. )
  2080. parsedata = \
  2081. (
  2082. # Some strings that won't match the r.e.
  2083. ('hello', N),
  2084. ('1970 -01Z', N),
  2085. ('0001-02z', N),
  2086. # Invalid ranges
  2087. ('2001-00Z', N),
  2088. ('2001-13Z', N),
  2089. # Whitespace
  2090. (ws + '1970-01Z' + ws, (1970, 1)),
  2091. # No timezones
  2092. ('11971-02', (11971, 2)),
  2093. ('1971-02', (1971, 2)),
  2094. ('-1971-02', (-1971, 2)),
  2095. # Non-zulu
  2096. ('11971-02-07:08', (11971, 2)),
  2097. ('11971-02+07:08', (11971, 1)),
  2098. ('-11971-02-07:08', (-11971, 2)),
  2099. ('-11971-02+07:08', (-11971, 1)),
  2100. ('1971-02-07:08', (1971, 2)),
  2101. ('1971-02+07:08', (1971, 1)),
  2102. ('-1971-02-07:08', (-1971, 2)),
  2103. ('-1971-02+07:08', (-1971, 1)),
  2104. # Edgepoints (ranges)
  2105. ('2001-01Z', (2001, 1)),
  2106. ('2001-12Z', (2001, 12)),
  2107. # Edgepoints (crossing boundaries)
  2108. ('0001-01+07:08', (0, 12)),
  2109. ('-0004-01+07:08', (-5, 12)),
  2110. ('2001-03+07:08', (2001, 2)),
  2111. ('2000-03+07:08', (2000, 2)),
  2112. ('1900-03+07:08', (1900, 2)),
  2113. )
  2114. for t in (gYearMonthType,):
  2115. self.allTests(t, baddata, gooddata, parsedata)
  2116. def testGYearAndYear(self):
  2117. baddata = \
  2118. (
  2119. 'hello',
  2120. ('hello',),
  2121. (1, 2),
  2122. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  2123. (2.5,),
  2124. )
  2125. gooddata = \
  2126. (
  2127. (1L, '0001Z', 1),
  2128. (10, '0010Z', 10),
  2129. (100, '0100Z', 100),
  2130. (1970, '1970Z', 1970),
  2131. (-1970, '-1970Z', -1970),
  2132. (1970L, '1970Z', 1970),
  2133. (11990.0, '11990Z', 11990),
  2134. (1e15, '1000000000000000Z', 1e15),
  2135. (-1e15, '-1000000000000000Z', -1e15),
  2136. (1000000000000000L, '1000000000000000Z', 1e15),
  2137. (-1000000000000000L, '-1000000000000000Z', -1e15),
  2138. )
  2139. parsedata = \
  2140. (
  2141. # Some strings that won't match the r.e.
  2142. ('hello', N),
  2143. ('197OZ', N),
  2144. ('0001z', N),
  2145. # Whitespace
  2146. (ws + '1970Z' + ws, 1970),
  2147. # No timezones
  2148. ('11971', 11971),
  2149. ('1971', 1971),
  2150. ('-1971', -1971),
  2151. # Non-zulu
  2152. ('11971-07:08', 11971),
  2153. ('11971+07:08', 11970),
  2154. ('-11971-07:08', -11971),
  2155. ('-11971+07:08', -11972),
  2156. ('1971-07:08', 1971),
  2157. ('1971+07:08', 1970),
  2158. ('-1971-07:08', -1971),
  2159. ('-1971+07:08', -1972),
  2160. # Edgepoints (crossing boundaries)
  2161. ('0001+07:08', 0),
  2162. ('-0004+07:08', -5),
  2163. )
  2164. for t in (gYearType, yearType):
  2165. self.allTests(t, baddata, gooddata, parsedata)
  2166. def testCentury(self):
  2167. baddata = \
  2168. (
  2169. 'hello',
  2170. ('hello',),
  2171. (1, 2),
  2172. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  2173. (2.5,),
  2174. )
  2175. gooddata = \
  2176. (
  2177. (1L, '01Z', 1),
  2178. (10, '10Z', 10),
  2179. (100, '100Z', 100),
  2180. (19, '19Z', 19),
  2181. (-19, '-19Z', -19),
  2182. (19L, '19Z', 19),
  2183. (119.0, '119Z', 119),
  2184. (1e15, '1000000000000000Z', 1e15),
  2185. (-1e15, '-1000000000000000Z', -1e15),
  2186. (1000000000000000L, '1000000000000000Z', 1e15),
  2187. (-1000000000000000L, '-1000000000000000Z', -1e15),
  2188. )
  2189. parsedata = \
  2190. (
  2191. # Some strings that won't match the r.e.
  2192. ('hello', N),
  2193. ('197OZ', N),
  2194. ('0001z', N),
  2195. # Whitespace
  2196. (ws + '1970Z' + ws, 1970),
  2197. # No timezones
  2198. ('11971', 11971),
  2199. ('1971', 1971),
  2200. ('-1971', -1971),
  2201. # Non-zulu
  2202. ('11971-07:08', 11971),
  2203. ('11971+07:08', 11970),
  2204. ('-11971-07:08', -11971),
  2205. ('-11971+07:08', -11972),
  2206. ('1971-07:08', 1971),
  2207. ('1971+07:08', 1970),
  2208. ('-1971-07:08', -1971),
  2209. ('-1971+07:08', -1972),
  2210. # Edgepoints (crossing boundaries)
  2211. ('0001+07:08', 0),
  2212. ('-0004+07:08', -5),
  2213. )
  2214. for t in (centuryType,):
  2215. self.allTests(t, baddata, gooddata, parsedata)
  2216. def testGMonthDayAndRecurringDate(self):
  2217. baddata = \
  2218. (
  2219. 'hello',
  2220. ('hello',),
  2221. (3, 4, 5),
  2222. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  2223. (4, 5, 'hello'),
  2224. (2.5, 3),
  2225. (0, 3),
  2226. (13, 3),
  2227. (1, 0),
  2228. (1, 32),
  2229. (2, 29),
  2230. (3, 32),
  2231. (4, 31),
  2232. (5, 32),
  2233. (6, 31),
  2234. (7, 32),
  2235. (8, 32),
  2236. (9, 31),
  2237. (10, 32),
  2238. (11, 31),
  2239. (12, 32),
  2240. )
  2241. gooddata = \
  2242. (
  2243. (1L, '--01-01Z', (1, 1)),
  2244. (1.5, '--01-01Z', (1, 1)),
  2245. ((2,), '--02-01Z', (2, 1)),
  2246. ((2, 3), '--02-03Z', (2, 3)),
  2247. ((10, 2), '--10-02Z', (10, 2)),
  2248. )
  2249. parsedata = \
  2250. (
  2251. # Some strings that won't match the r.e.
  2252. ('hello', N),
  2253. ('--01 -01Z', N),
  2254. ('--02-03z', N),
  2255. # Invalid ranges
  2256. ('--00-03Z', N),
  2257. ('--13-03Z', N),
  2258. ('--01-32Z', N),
  2259. ('--02-00Z', N),
  2260. ('--02-29Z', N),
  2261. ('--03-32Z', N),
  2262. ('--04-31Z', N),
  2263. ('--05-32Z', N),
  2264. ('--06-31Z', N),
  2265. ('--07-32Z', N),
  2266. ('--08-32Z', N),
  2267. ('--09-31Z', N),
  2268. ('--10-32Z', N),
  2269. ('--11-31Z', N),
  2270. ('--12-32Z', N),
  2271. # Whitespace
  2272. (ws + '--01-01Z' + ws, (1, 1)),
  2273. # No timezones
  2274. ('--02-03', (2, 3)),
  2275. # Non-zulu
  2276. ('--02-03-07:08', (2, 3)),
  2277. ('--02-03+07:08', (2, 2)),
  2278. # Edgepoints (ranges)
  2279. ('--01-03Z', (1, 3)),
  2280. ('--12-03Z', (12, 3)),
  2281. ('--01-31Z', (1, 31)),
  2282. ('--02-01Z', (2, 1)),
  2283. ('--02-28Z', (2, 28)),
  2284. ('--03-31Z', (3, 31)),
  2285. ('--04-30Z', (4, 30)),
  2286. ('--05-31Z', (5, 31)),
  2287. ('--06-30Z', (6, 30)),
  2288. ('--07-31Z', (7, 31)),
  2289. ('--08-31Z', (8, 31)),
  2290. ('--09-30Z', (9, 30)),
  2291. ('--10-31Z', (10, 31)),
  2292. ('--11-30Z', (11, 30)),
  2293. ('--12-31Z', (12, 31)),
  2294. # Edgepoints (crossing boundaries)
  2295. ('--01-01+07:08', (12, 31)),
  2296. ('--03-01+07:08', (2, 28)),
  2297. )
  2298. for t in (gMonthDayType, recurringDateType):
  2299. self.allTests(t, baddata, gooddata, parsedata)
  2300. def testGMonthAndMonth(self):
  2301. baddata = \
  2302. (
  2303. 'hello',
  2304. ('hello',),
  2305. (3, 4,),
  2306. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  2307. (2.5,),
  2308. (0,),
  2309. (13,),
  2310. )
  2311. gooddata = \
  2312. (
  2313. (1L, '--01--Z', 1),
  2314. ((2,), '--02--Z', 2),
  2315. ((10,), '--10--Z', 10),
  2316. )
  2317. parsedata = \
  2318. (
  2319. # Some strings that won't match the r.e.
  2320. ('hello', N),
  2321. ('--01 --Z', N),
  2322. ('--03--z', N),
  2323. # Invalid ranges
  2324. ('--00--Z', N),
  2325. ('--13--Z', N),
  2326. # Whitespace
  2327. (ws + '--01--Z' + ws, 1),
  2328. # No timezones
  2329. ('--03--', 3),
  2330. # Non-zulu
  2331. ('--03---07:08', 3),
  2332. ('--03--+07:08', 2),
  2333. # Edgepoints (ranges)
  2334. ('--01--Z', 1),
  2335. ('--12--Z', 12),
  2336. # Edgepoints (crossing boundaries)
  2337. ('--01--+07:08', 12),
  2338. ('--12---07:08', 12),
  2339. )
  2340. for t in (gMonthType, monthType):
  2341. self.allTests(t, baddata, gooddata, parsedata)
  2342. def testGDayAndRecurringDay(self):
  2343. baddata = \
  2344. (
  2345. 'hello',
  2346. ('hello',),
  2347. (3, 4,),
  2348. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  2349. (2.5,),
  2350. (0,),
  2351. (32,),
  2352. )
  2353. gooddata = \
  2354. (
  2355. (1L, '---01Z', 1),
  2356. ((2,), '---02Z', 2),
  2357. ((10,), '---10Z', 10),
  2358. )
  2359. parsedata = \
  2360. (
  2361. # Some strings that won't match the r.e.
  2362. ('hello', N),
  2363. ('---01 Z', N),
  2364. ('---03z', N),
  2365. # Invalid ranges
  2366. ('---00Z', N),
  2367. ('---32Z', N),
  2368. # Whitespace
  2369. (ws + '---01Z' + ws, 1),
  2370. # No timezones
  2371. ('---03', 3),
  2372. # Non-zulu
  2373. ('---03-07:08', 3),
  2374. ('---03+07:08', 2),
  2375. # Edgepoints (ranges)
  2376. ('---01Z', 1),
  2377. ('---31Z', 31),
  2378. # Edgepoints (crossing boundaries)
  2379. ('---01+07:08', 31),
  2380. ('---31-07:08', 31),
  2381. )
  2382. for t in (gDayType, recurringDayType):
  2383. self.allTests(t, baddata, gooddata, parsedata)
  2384. def testInteger(self):
  2385. # First some things that shouldn't be valid
  2386. test = ('hello', 3.14, (), [], {})
  2387. t = integerType
  2388. for i in test:
  2389. try:
  2390. t(i)
  2391. raise AssertionError, \
  2392. "instantiated a %s with a bad value (%s)" % \
  2393. (t.__name__, repr(i))
  2394. except AssertionError:
  2395. raise
  2396. except ValueError:
  2397. pass
  2398. # Now some things that should
  2399. for i in (10, 23L, 1111111111111111111111111111111111111111111111111111L):
  2400. x = integerType(i)
  2401. d = x._marshalData()
  2402. if d != str(i):
  2403. raise AssertionError, "expected %d, got %s" % (i, d)
  2404. y = buildSOAP(x)
  2405. z = parseSOAPRPC(y)
  2406. if z != i:
  2407. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  2408. # Now test parsing, both valid and invalid
  2409. test = (('hello', N), ('3.14', N), ('10 000', N),
  2410. ('1', 1),
  2411. ('123456789012345678901234567890', 123456789012345678901234567890L),
  2412. (ws + '12' + ws, 12))
  2413. for i in test:
  2414. try:
  2415. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4],
  2416. i[0]))
  2417. if z != i[1]:
  2418. raise AssertionError, "%s: expected %s, got %s" % \
  2419. (i[0], i[1], repr(z))
  2420. except AssertionError:
  2421. raise
  2422. except:
  2423. if i[1] != N:
  2424. raise AssertionError, \
  2425. "parsing %s as %s threw exception %s:%s" % \
  2426. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  2427. def testNonPositiveInteger(self):
  2428. # First some things that shouldn't be valid
  2429. test = ('hello', 3.14, (), [], {}, 1, 23)
  2430. for t in (nonPositiveIntegerType, non_Positive_IntegerType):
  2431. for i in test:
  2432. try:
  2433. t(i)
  2434. raise AssertionError, \
  2435. "instantiated a t with a bad value (%s)" % \
  2436. (t.__name__, repr(i))
  2437. except AssertionError:
  2438. raise
  2439. except ValueError:
  2440. pass
  2441. # Now some things that should
  2442. for i in (0, -23L, -1111111111111111111111111111111111111111111111111L):
  2443. x = t(i)
  2444. d = x._marshalData()
  2445. if d != str(i):
  2446. raise AssertionError, "expected %d, got %s" % (i, d)
  2447. y = buildSOAP(x)
  2448. z = parseSOAPRPC(y)
  2449. if z != i:
  2450. raise AssertionError, "%s: expected %s, got %s" % \
  2451. (i[0], i[1], repr(z))
  2452. # Now test parsing, both valid and invalid
  2453. test = (('hello', N), ('3.14', N), ('-10 000', N), ('1', N),
  2454. ('0', 0),
  2455. ('-1', -1),
  2456. ('-123456789012345678901234567890', -123456789012345678901234567890L),
  2457. (ws + '-12' + ws, -12))
  2458. for i in test:
  2459. try:
  2460. if t == nonPositiveIntegerType:
  2461. n = t.__name__[:-4]
  2462. else:
  2463. n = 'non-positive-integer'
  2464. z = parseSOAPRPC(self.build_xml(t._validURIs[0], n, i[0]))
  2465. if z != i[1]:
  2466. raise AssertionError, "%s: expected %s, got %s" % \
  2467. (i[0], i[1], repr(z))
  2468. except AssertionError:
  2469. raise
  2470. except:
  2471. if i[1] != N:
  2472. raise AssertionError, \
  2473. "parsing %s as %s threw exception %s:%s" % \
  2474. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  2475. def testNegativeInteger(self):
  2476. # First some things that shouldn't be valid
  2477. test = ('hello', 3.14, (), [], {}, 0, 23)
  2478. for t in (negativeIntegerType, negative_IntegerType):
  2479. for i in test:
  2480. try:
  2481. t(i)
  2482. raise AssertionError, \
  2483. "instantiated a %s with a bad value (%s)" % \
  2484. (t.__name__, repr(i))
  2485. except AssertionError:
  2486. raise
  2487. except ValueError:
  2488. pass
  2489. # Now some things that should
  2490. for i in (-1, -23L, -111111111111111111111111111111111111111111111111L):
  2491. x = t(i)
  2492. d = x._marshalData()
  2493. if d != str(i):
  2494. raise AssertionError, "expected %d, got %s" % (i, d)
  2495. y = buildSOAP(x)
  2496. z = parseSOAPRPC(y)
  2497. if z != i:
  2498. raise AssertionError, "%s: expected %s, got %s" % \
  2499. (i[0], i[1], repr(z))
  2500. # Now test parsing, both valid and invalid
  2501. test = (('hello', N), ('3.14', N), ('-10 000', N), ('1', N),
  2502. ('0', N),
  2503. ('-1', -1),
  2504. ('-123456789012345678901234567890', -123456789012345678901234567890L),
  2505. (ws + '-12' + ws, -12))
  2506. for i in test:
  2507. try:
  2508. if t == negativeIntegerType:
  2509. n = t.__name__[:-4]
  2510. else:
  2511. n = 'negative-integer'
  2512. z = parseSOAPRPC(self.build_xml(t._validURIs[0], n, i[0]))
  2513. if z != i[1]:
  2514. raise AssertionError, "expected %s, got %s" % (i[1], repr(z))
  2515. except AssertionError:
  2516. raise
  2517. except:
  2518. if i[1] != N:
  2519. raise AssertionError, \
  2520. "parsing %s as %s threw exception %s:%s" % \
  2521. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  2522. def testLong(self):
  2523. # First some things that shouldn't be valid
  2524. test = ('hello', 3.14, (), [], {},
  2525. -9223372036854775809L, 9223372036854775808L)
  2526. t = longType
  2527. for i in test:
  2528. try:
  2529. t(i)
  2530. raise AssertionError, \
  2531. "instantiated a %s with a bad value (%s)" % \
  2532. (t.__name__, repr(i))
  2533. except AssertionError:
  2534. raise
  2535. except ValueError:
  2536. pass
  2537. # Now some things that should
  2538. for i in (-1, -23L, -9223372036854775808L, 9223372036854775807L):
  2539. x = t(i)
  2540. d = x._marshalData()
  2541. if d != str(i):
  2542. raise AssertionError, "expected %d, got %s" % (i, d)
  2543. y = buildSOAP(x)
  2544. z = parseSOAPRPC(y)
  2545. if z != i:
  2546. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  2547. # Now test parsing, both valid and invalid
  2548. test = (('hello', N), ('3.14', N), ('-10 000', N),
  2549. ('-9223372036854775809', N), ('9223372036854775808', N),
  2550. ('-1', -1), ('0', 0), ('1', 1),
  2551. ('-9223372036854775808', -9223372036854775808L),
  2552. ('9223372036854775807', 9223372036854775807L),
  2553. (ws + '-12' + ws, -12))
  2554. for i in test:
  2555. try:
  2556. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  2557. if z != i[1]:
  2558. raise AssertionError, "%s: expected %s, got %s" % \
  2559. (i[0], i[1], repr(z))
  2560. except AssertionError:
  2561. raise
  2562. except:
  2563. if i[1] != N:
  2564. raise AssertionError, \
  2565. "parsing %s as %s threw exception %s:%s" % \
  2566. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  2567. def testInt(self):
  2568. # First some things that shouldn't be valid
  2569. test = ('hello', 3.14, (), [], {}, -2147483649L, 2147483648L)
  2570. t = intType
  2571. for i in test:
  2572. try:
  2573. t(i)
  2574. raise AssertionError, \
  2575. "instantiated a %s with a bad value (%s)" % \
  2576. (t.__name__, repr(i))
  2577. except AssertionError:
  2578. raise
  2579. except ValueError:
  2580. pass
  2581. # Now some things that should
  2582. for i in (-1, -23L, -2147483648L, 2147483647):
  2583. x = intType(i)
  2584. d = x._marshalData()
  2585. if d != str(i):
  2586. raise AssertionError, "expected %d, got %s" % (i, d)
  2587. y = buildSOAP(x)
  2588. z = parseSOAPRPC(y)
  2589. if z != i:
  2590. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  2591. # Now test parsing, both valid and invalid
  2592. test = (('hello', N), ('3.14', N), ('-10 000', N),
  2593. ('-2147483649', N), ('2147483648', N),
  2594. ('-1', -1), ('0', 0), ('1', 1),
  2595. ('-2147483648', -2147483648L),
  2596. ('2147483647', 2147483647),
  2597. (ws + '-12' + ws, -12))
  2598. for i in test:
  2599. try:
  2600. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  2601. if z != i[1]:
  2602. raise AssertionError, "%s: expected %s, got %s" % \
  2603. (i[0], i[1], repr(z))
  2604. except AssertionError:
  2605. raise
  2606. except:
  2607. if i[1] != N:
  2608. raise AssertionError, \
  2609. "parsing %s as %s threw exception %s:%s" % \
  2610. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  2611. def testShort(self):
  2612. # First some things that shouldn't be valid
  2613. test = ('hello', 3.14, (), [], {}, -32769, 32768)
  2614. t = shortType
  2615. for i in test:
  2616. try:
  2617. t(i)
  2618. raise AssertionError, \
  2619. "instantiated a %s with a bad value (%s)" % \
  2620. (t.__name__, repr(i))
  2621. except AssertionError:
  2622. raise
  2623. except ValueError:
  2624. pass
  2625. # Now some things that should
  2626. for i in (-1, -23L, -32768, 32767):
  2627. x = t(i)
  2628. d = x._marshalData()
  2629. if d != str(i):
  2630. raise AssertionError, "expected %d, got %s" % (i, d)
  2631. y = buildSOAP(x)
  2632. z = parseSOAPRPC(y)
  2633. if z != i:
  2634. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  2635. # Now test parsing, both valid and invalid
  2636. test = (('hello', N), ('3.14', N), ('-10 000', N),
  2637. ('-32769', N), ('32768', N),
  2638. ('-1', -1), ('0', 0), ('1', 1),
  2639. ('-32768', -32768),
  2640. ('32767', 32767),
  2641. (ws + '-12' + ws, -12))
  2642. for i in test:
  2643. try:
  2644. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  2645. if z != i[1]:
  2646. raise AssertionError, "%s: expected %s, got %s" % \
  2647. (i[0], i[1], repr(z))
  2648. except AssertionError:
  2649. raise
  2650. except:
  2651. if i[1] != N:
  2652. raise AssertionError, \
  2653. "parsing %s as %s threw exception %s:%s" % \
  2654. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  2655. def testByte(self):
  2656. # First some things that shouldn't be valid
  2657. test = ('hello', 3.14, (), [], {}, -129, 128)
  2658. t = byteType
  2659. for i in test:
  2660. try:
  2661. t(i)
  2662. raise AssertionError, \
  2663. "instantiated a %s with a bad value (%s)" % \
  2664. (t.__name__, repr(i))
  2665. except AssertionError:
  2666. raise
  2667. except ValueError:
  2668. pass
  2669. # Now some things that should
  2670. for i in (-1, -23L, -128, 127):
  2671. x = t(i)
  2672. d = x._marshalData()
  2673. if d != str(i):
  2674. raise AssertionError, "expected %d, got %s" % (i, d)
  2675. y = buildSOAP(x)
  2676. z = parseSOAPRPC(y)
  2677. if z != i:
  2678. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  2679. # Now test parsing, both valid and invalid
  2680. test = (('hello', N), ('3.14', N), ('-10 000', N),
  2681. ('-129', N), ('128', N),
  2682. ('-1', -1), ('0', 0), ('1', 1),
  2683. ('-128', -128),
  2684. ('127', 127),
  2685. (ws + '-12' + ws, -12))
  2686. for i in test:
  2687. try:
  2688. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  2689. if z != i[1]:
  2690. raise AssertionError, "%s: expected %s, got %s" % \
  2691. (i[0], i[1], repr(z))
  2692. except AssertionError:
  2693. raise
  2694. except:
  2695. if i[1] != N:
  2696. raise AssertionError, \
  2697. "parsing %s as %s threw exception %s:%s" % \
  2698. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  2699. def testNonNegativeInteger(self):
  2700. # First some things that shouldn't be valid
  2701. test = ('hello', 3.14, (), [], {}, -42, -1)
  2702. for t in (nonNegativeIntegerType, non_Negative_IntegerType):
  2703. for i in test:
  2704. try:
  2705. t(i)
  2706. raise AssertionError, \
  2707. "instantiated a %s with a bad value (%s)" % \
  2708. (t.__name__, repr(i))
  2709. except AssertionError:
  2710. raise
  2711. except ValueError:
  2712. pass
  2713. # Now some things that should
  2714. for i in (0, 1, 23L, 111111111111111111111111111111111111111111111111L):
  2715. x = t(i)
  2716. d = x._marshalData()
  2717. if d != str(i):
  2718. raise AssertionError, "expected %d, got %s" % (i, d)
  2719. y = buildSOAP(x)
  2720. z = parseSOAPRPC(y)
  2721. if z != i:
  2722. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  2723. # Now test parsing, both valid and invalid
  2724. test = (('hello', N), ('3.14', N), ('-10 000', N), ('-1', N),
  2725. ('0', 0),
  2726. ('1', 1),
  2727. ('123456789012345678901234567890', 123456789012345678901234567890L),
  2728. (ws + '12' + ws, 12))
  2729. for i in test:
  2730. try:
  2731. if t == nonNegativeIntegerType:
  2732. n = t.__name__[:-4]
  2733. else:
  2734. n = 'non-negative-integer'
  2735. z = parseSOAPRPC(self.build_xml(t._validURIs[0], n, i[0]))
  2736. if z != i[1]:
  2737. raise AssertionError, "%s: expected %s, got %s" % \
  2738. (i[0], i[1], repr(z))
  2739. except AssertionError:
  2740. raise
  2741. except:
  2742. if i[1] != N:
  2743. raise AssertionError, \
  2744. "parsing %s as %s threw exception %s:%s" % \
  2745. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  2746. def testUnsignedLong(self):
  2747. # First some things that shouldn't be valid
  2748. test = ('hello', 3.14, (), [], {}, -42, -1, 18446744073709551616L)
  2749. t = unsignedLongType
  2750. for i in test:
  2751. try:
  2752. t(i)
  2753. raise AssertionError, \
  2754. "instantiated a %s with a bad value (%s)" % \
  2755. (t.__name__, repr(i))
  2756. except AssertionError:
  2757. raise
  2758. except ValueError:
  2759. pass
  2760. # Now some things that should
  2761. for i in (0, 23L, 18446744073709551615L):
  2762. x = t(i)
  2763. d = x._marshalData()
  2764. if d != str(i):
  2765. raise AssertionError, "expected %d, got %s" % (i, d)
  2766. y = buildSOAP(x)
  2767. z = parseSOAPRPC(y)
  2768. if z != i:
  2769. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  2770. # Now test parsing, both valid and invalid
  2771. test = (('hello', N), ('3.14', N), ('-10 000', N), ('-1', N),
  2772. ('18446744073709551616', N),
  2773. ('0', 0), ('1', 1),
  2774. ('18446744073709551615', 18446744073709551615L),
  2775. (ws + '12' + ws, 12))
  2776. for i in test:
  2777. try:
  2778. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  2779. if z != i[1]:
  2780. raise AssertionError, "%s: expected %s, got %s" % \
  2781. (i[0], i[1], repr(z))
  2782. except AssertionError:
  2783. raise
  2784. except:
  2785. if i[1] != N:
  2786. raise AssertionError, \
  2787. "parsing %s as %s threw exception %s:%s" % \
  2788. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  2789. def testUnsignedInt(self):
  2790. # First some things that shouldn't be valid
  2791. test = ('hello', 3.14, (), [], {}, -42, -1, 4294967296L)
  2792. t = unsignedIntType
  2793. for i in test:
  2794. try:
  2795. t(i)
  2796. raise AssertionError, \
  2797. "instantiated a %s with a bad value (%s)" % \
  2798. (t.__name__, repr(i))
  2799. except AssertionError:
  2800. raise
  2801. except ValueError:
  2802. pass
  2803. # Now some things that should
  2804. for i in (0, 23L, 4294967295L):
  2805. x = t(i)
  2806. d = x._marshalData()
  2807. if d != str(i):
  2808. raise AssertionError, "expected %d, got %s" % (i, d)
  2809. y = buildSOAP(x)
  2810. z = parseSOAPRPC(y)
  2811. if z != i:
  2812. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  2813. # Now test parsing, both valid and invalid
  2814. test = (('hello', N), ('3.14', N), ('-10 000', N), ('-1', N),
  2815. ('4294967296', N),
  2816. ('0', 0), ('1', 1),
  2817. ('4294967295', 4294967295L),
  2818. (ws + '12' + ws, 12))
  2819. for i in test:
  2820. try:
  2821. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  2822. if z != i[1]:
  2823. raise AssertionError, "%s: expected %s, got %s" % \
  2824. (i[0], i[1], repr(z))
  2825. except AssertionError:
  2826. raise
  2827. except:
  2828. if i[1] != N:
  2829. raise AssertionError, \
  2830. "parsing %s as %s threw exception %s:%s" % \
  2831. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  2832. def testUnsignedShort(self):
  2833. # First some things that shouldn't be valid
  2834. test = ('hello', 3.14, (), [], {}, -42, -1, 65536)
  2835. t = unsignedShortType
  2836. for i in test:
  2837. try:
  2838. t(i)
  2839. raise AssertionError, \
  2840. "instantiated a %s with a bad value (%s)" % \
  2841. (t.__name__, repr(i))
  2842. except AssertionError:
  2843. raise
  2844. except ValueError:
  2845. pass
  2846. # Now some things that should
  2847. for i in (0, 23L, 65535):
  2848. x = t(i)
  2849. d = x._marshalData()
  2850. if d != str(i):
  2851. raise AssertionError, "expected %d, got %s" % (i, d)
  2852. y = buildSOAP(x)
  2853. z = parseSOAPRPC(y)
  2854. if z != i:
  2855. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  2856. # Now test parsing, both valid and invalid
  2857. test = (('hello', N), ('3.14', N), ('-10 000', N), ('-1', N),
  2858. ('65536', N),
  2859. ('0', 0), ('1', 1),
  2860. ('65535', 65535),
  2861. (ws + '12' + ws, 12))
  2862. for i in test:
  2863. try:
  2864. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  2865. if z != i[1]:
  2866. raise AssertionError, "%s: expected %s, got %s" % \
  2867. (i[0], i[1], repr(z))
  2868. except AssertionError:
  2869. raise
  2870. except:
  2871. if i[1] != N:
  2872. raise AssertionError, \
  2873. "parsing %s as %s threw exception %s:%s" % \
  2874. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  2875. def testUnsignedByte(self):
  2876. # First some things that shouldn't be valid
  2877. test = ('hello', 3.14, (), [], {}, -42, -1, 256)
  2878. t = unsignedByteType
  2879. for i in test:
  2880. try:
  2881. t(i)
  2882. raise AssertionError, \
  2883. "instantiated a %s with a bad value (%s)" % \
  2884. (t.__name__, repr(i))
  2885. except AssertionError:
  2886. raise
  2887. except ValueError:
  2888. pass
  2889. # Now some things that should
  2890. for i in (0, 23L, 255):
  2891. x = t(i)
  2892. d = x._marshalData()
  2893. if d != str(i):
  2894. raise AssertionError, "expected %d, got %s" % (i, d)
  2895. y = buildSOAP(x)
  2896. z = parseSOAPRPC(y)
  2897. if z != i:
  2898. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  2899. # Now test parsing, both valid and invalid
  2900. test = (('hello', N), ('3.14', N), ('-10 000', N), ('-1', N),
  2901. ('256', N),
  2902. ('0', 0), ('1', 1),
  2903. ('255', 255),
  2904. (ws + '12' + ws, 12))
  2905. for i in test:
  2906. try:
  2907. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  2908. if z != i[1]:
  2909. raise AssertionError, "%s: expected %s, got %s" % \
  2910. (i[0], i[1], repr(z))
  2911. except AssertionError:
  2912. raise
  2913. except:
  2914. if i[1] != N:
  2915. raise AssertionError, \
  2916. "parsing %s as %s threw exception %s:%s" % \
  2917. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  2918. def testPositiveInteger(self):
  2919. # First some things that shouldn't be valid
  2920. test = ('hello', 3.14, (), [], {}, -42, -1, 0)
  2921. for t in (positiveIntegerType, positive_IntegerType):
  2922. for i in test:
  2923. try:
  2924. t(i)
  2925. raise AssertionError, \
  2926. "instantiated a t with a bad value (%s)" % \
  2927. (t.__name__, repr(i))
  2928. except AssertionError:
  2929. raise
  2930. except ValueError:
  2931. pass
  2932. # Now some things that should
  2933. for i in (1, 23L, 1111111111111111111111111111111111111111111111111111L):
  2934. x = t(i)
  2935. d = x._marshalData()
  2936. if d != str(i):
  2937. raise AssertionError, "expected %d, got %s" % (i, d)
  2938. y = buildSOAP(x)
  2939. z = parseSOAPRPC(y)
  2940. if z != i:
  2941. raise AssertionError, "expected %s, got %s" % (repr(i), repr(z))
  2942. # Now test parsing, both valid and invalid
  2943. test = (('hello', N), ('3.14', N), ('-10 000', N), ('-1', N),
  2944. ('0', N), ('1', 1),
  2945. ('123456789012345678901234567890', 123456789012345678901234567890L),
  2946. (ws + '12' + ws, 12))
  2947. for i in test:
  2948. try:
  2949. if t == positiveIntegerType:
  2950. n = t.__name__[:-4]
  2951. else:
  2952. n = 'positive-integer'
  2953. z = parseSOAPRPC(self.build_xml(t._validURIs[0], n, i[0]))
  2954. if z != i[1]:
  2955. raise AssertionError, "%s: expected %s, got %s" % \
  2956. (i[0], i[1], repr(z))
  2957. except AssertionError:
  2958. raise
  2959. except:
  2960. if i[1] != N:
  2961. raise AssertionError, \
  2962. "parsing %s as %s threw exception %s:%s" % \
  2963. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1])
  2964. def testUntyped(self):
  2965. # Make sure untypedType really isn't typed
  2966. a = stringType('hello', name = 'a')
  2967. b = untypedType('earth', name = 'b')
  2968. x = buildSOAP((a, b))
  2969. #print "x=",x
  2970. self.failUnless(x.find('<a xsi:type="xsd:string" SOAP-ENC:root="1">hello</a>') != -1)
  2971. self.failUnless(x.find('<b SOAP-ENC:root="1">earth</b>') != -1)
  2972. # Now some Array tests
  2973. def testArray(self):
  2974. env = '''<?xml version="1.0" encoding="UTF-8"?>
  2975. <SOAP-ENV:Envelope SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsd2="http://www.w3.org/2000/10/XMLSchema" xmlns:xsd3="http://www.w3.org/2001/XMLSchema" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/">
  2976. %s
  2977. </SOAP-ENV:Envelope>'''
  2978. xml = env % '''<SOAP-ENV:Body>
  2979. <_1 SOAP-ENC:arrayType="xsd:int[4]" SOAP-ENC:offset="[2]" xsi:type="SOAP-ENC:Array">
  2980. <_2 SOAP-ENC:arrayType="xsd:int[2]" xsi:type="SOAP-ENC:Array">
  2981. <item>1</item>
  2982. <item>2</item>
  2983. </_2>
  2984. <_3 SOAP-ENC:arrayType="xsd:int[2]" xsi:type="SOAP-ENC:Array">
  2985. <item>3</item>
  2986. <item>4</item>
  2987. </_3>
  2988. </_1>
  2989. </SOAP-ENV:Body>'''
  2990. x = parseSOAPRPC(xml)
  2991. self.assertEquals( x , [None, None, [1, 2], [3, 4]])
  2992. xml = env % '''<SOAP-ENV:Body>
  2993. <_1 SOAP-ENC:arrayType="xsd:int[3,4,2]" SOAP-ENC:offset="[17]" xsi:type="SOAP-ENC:Array">
  2994. <item>1</item>
  2995. <item>2</item>
  2996. <item>3</item>
  2997. <item>4</item>
  2998. <item>5</item>
  2999. <item>6</item>
  3000. <item>7</item>
  3001. </_1>
  3002. </SOAP-ENV:Body>'''
  3003. x = parseSOAPRPC(xml)
  3004. self.assertEquals( x , [
  3005. [[None, None], [None, None], [None, None], [None, None]],
  3006. [[None, None], [None, None], [None, None], [None, None]],
  3007. [[None, 1], [2, 3], [4, 5], [6, 7]]
  3008. ])
  3009. xml = env % '''<SOAP-ENV:Body>
  3010. <_1 SOAP-ENC:arrayType="xsd:int[3,4,2]" xsi:type="SOAP-ENC:Array">
  3011. <item SOAP-ENC:position="[17]">-17</item>
  3012. <item SOAP-ENC:position="[13]">13</item>
  3013. <item SOAP-ENC:position="[22]">-22</item>
  3014. <item SOAP-ENC:position="[1]">1</item>
  3015. <item SOAP-ENC:position="[17]">17</item>
  3016. <item SOAP-ENC:position="[23]">23</item>
  3017. <item SOAP-ENC:position="[6]">6</item>
  3018. </_1>
  3019. </SOAP-ENV:Body>'''
  3020. x = parseSOAPRPC(xml)
  3021. self.assertEquals( x , [
  3022. [[None, 1L], [None, None], [None, None], [6L, None]],
  3023. [[None, None], [None, None], [None, 13L], [None, None]],
  3024. [[None, 17L], [None, None], [None, None], [-22L, 23L]]
  3025. ])
  3026. xml = env % '''<SOAP-ENV:Body>
  3027. <_1 SOAP-ENC:arrayType="xsd:int[4]" SOAP-ENC:offset="[3]" xsi:type="SOAP-ENC:Array">
  3028. <item SOAP-ENC:position="[2]">2</item>
  3029. <item SOAP-ENC:position="[0]">0</item>
  3030. <item SOAP-ENC:position="[1]">1</item>
  3031. <item SOAP-ENC:position="[3]">3</item>
  3032. </_1>
  3033. </SOAP-ENV:Body>'''
  3034. x = parseSOAPRPC(xml)
  3035. self.assertEquals( x , [0, 1, 2, 3])
  3036. xml = env % '''<SOAP-ENV:Body>
  3037. <_1 SOAP-ENC:arrayType="xsd:int[2,3,4]" SOAP-ENC:offset="[23]" xsi:type="SOAP-ENC:Array">
  3038. </_1>
  3039. </SOAP-ENV:Body>'''
  3040. x = parseSOAPRPC(xml)
  3041. self.assertEquals( x , [
  3042. [
  3043. [None, None, None, None],
  3044. [None, None, None, None],
  3045. [None, None, None, None],
  3046. ],
  3047. [
  3048. [None, None, None, None],
  3049. [None, None, None, None],
  3050. [None, None, None, None],
  3051. ]
  3052. ])
  3053. xml = env % '''<SOAP-ENV:Body>
  3054. <_1 SOAP-ENC:arrayType="xsd:int[4]" SOAP-ENC:offset="[3]" xsi:type="SOAP-ENC:Array">
  3055. <item>2</item>
  3056. <item>3</item>
  3057. </_1>
  3058. </SOAP-ENV:Body>'''
  3059. try:
  3060. x = parseSOAPRPC(xml)
  3061. raise AssertionError, "full array parsed"
  3062. except AssertionError:
  3063. raise
  3064. except:
  3065. pass
  3066. xml = env % '''<SOAP-ENV:Body>
  3067. <_1 SOAP-ENC:arrayType="xsd:int[2,0,4]" xsi:type="SOAP-ENC:Array">
  3068. </_1>
  3069. </SOAP-ENV:Body>'''
  3070. try:
  3071. x = parseSOAPRPC(xml)
  3072. raise AssertionError, "array with bad dimension (0) parsed"
  3073. except AssertionError:
  3074. raise
  3075. except:
  3076. pass
  3077. xml = env % '''<SOAP-ENV:Body>
  3078. <_1 SOAP-ENC:arrayType="xsd:int[2,3,-4]" xsi:type="SOAP-ENC:Array">
  3079. </_1>
  3080. </SOAP-ENV:Body>'''
  3081. try:
  3082. x = parseSOAPRPC(xml)
  3083. raise AssertionError, "array with bad dimension (negative) parsed"
  3084. except AssertionError:
  3085. raise
  3086. except:
  3087. pass
  3088. xml = env % '''<SOAP-ENV:Body>
  3089. <_1 SOAP-ENC:arrayType="xsd:int[2,3,4.4]" xsi:type="SOAP-ENC:Array">
  3090. </_1>
  3091. </SOAP-ENV:Body>'''
  3092. try:
  3093. x = parseSOAPRPC(xml)
  3094. raise AssertionError, "array with bad dimension (non-integral) parsed"
  3095. except AssertionError:
  3096. raise
  3097. except:
  3098. pass
  3099. xml = env % '''<SOAP-ENV:Body>
  3100. <_1 SOAP-ENC:arrayType="xsd:int[2,hello,4]" xsi:type="SOAP-ENC:Array">
  3101. </_1>
  3102. </SOAP-ENV:Body>'''
  3103. try:
  3104. x = parseSOAPRPC(xml)
  3105. raise AssertionError, "array with bad dimension (non-numeric) parsed"
  3106. except AssertionError:
  3107. raise
  3108. except:
  3109. pass
  3110. xml = env % '''<SOAP-ENV:Body>
  3111. <_1 SOAP-ENC:arrayType="xsd:int[2,3,4]" SOAP-ENC:offset="[-4]" xsi:type="SOAP-ENC:Array">
  3112. </_1>
  3113. </SOAP-ENV:Body>'''
  3114. try:
  3115. x = parseSOAPRPC(xml)
  3116. raise AssertionError, "array with too large offset parsed"
  3117. except AssertionError:
  3118. raise
  3119. except:
  3120. pass
  3121. xml = env % '''<SOAP-ENV:Body>
  3122. <_1 SOAP-ENC:arrayType="xsd:int[2,3,4]" SOAP-ENC:offset="[24]" xsi:type="SOAP-ENC:Array">
  3123. </_1>
  3124. </SOAP-ENV:Body>'''
  3125. try:
  3126. x = parseSOAPRPC(xml)
  3127. raise AssertionError, "array with too large offset parsed"
  3128. except AssertionError:
  3129. raise
  3130. except:
  3131. pass
  3132. xml = env % '''<SOAP-ENV:Body>
  3133. <_1 SOAP-ENC:arrayType="xsd:int[2,3,4]" xsi:type="SOAP-ENC:Array">
  3134. <item SOAP-ENC:position="0">2</item>
  3135. <item>3</item>
  3136. </_1>
  3137. </SOAP-ENV:Body>'''
  3138. try:
  3139. x = parseSOAPRPC(xml)
  3140. raise AssertionError, "full array parsed"
  3141. except AssertionError:
  3142. raise
  3143. except:
  3144. pass
  3145. xml = env % '''<SOAP-ENV:Body>
  3146. <myFavoriteNumbers type="SOAP-ENC:Array" SOAP-ENC:arrayType="xsd:int[2]">
  3147. <number>3</number>
  3148. <number>4</number>
  3149. </myFavoriteNumbers>
  3150. </SOAP-ENV:Body>'''
  3151. x = parseSOAPRPC(xml)
  3152. self.assertEquals( x , [3, 4])
  3153. xml = env % '''<SOAP-ENV:Body>
  3154. <SOAP-ENC:Array SOAP-ENC:arrayType="xsd:ur-type[4]">
  3155. <thing xsi:type="xsd:int">12345</thing>
  3156. <thing xsi:type="xsd:decimal">6.789</thing>
  3157. <thing xsi:type="xsd:string">Of Mans First Disobedience, and the Fruit
  3158. Of that Forbidden Tree, whose mortal tast
  3159. Brought Death into the World, and all our woe,</thing>
  3160. <thing xsi:type="xsd2:uriReference">
  3161. http://www.dartmouth.edu/~milton/reading_room/
  3162. </thing>
  3163. </SOAP-ENC:Array>
  3164. </SOAP-ENV:Body>'''
  3165. x = parseSOAPRPC(xml)
  3166. self.assertEquals( x , [12345, 6.789, '''Of Mans First Disobedience, and the Fruit
  3167. Of that Forbidden Tree, whose mortal tast
  3168. Brought Death into the World, and all our woe,''',
  3169. 'http://www.dartmouth.edu/~milton/reading_room/'])
  3170. xml = env % '''<SOAP-ENV:Body>
  3171. <SOAP-ENC:Array SOAP-ENC:arrayType="xyz:Order[2]">
  3172. <Order>
  3173. <Product>Apple</Product>
  3174. <Price>1.56</Price>
  3175. </Order>
  3176. <Order>
  3177. <Product>Peach</Product>
  3178. <Price>1.48</Price>
  3179. </Order>
  3180. </SOAP-ENC:Array>
  3181. </SOAP-ENV:Body>'''
  3182. #x = parseSOAPRPC(xml)
  3183. #print "x=",x
  3184. xml = env % '''<SOAP-ENV:Body>
  3185. <SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[3]">
  3186. <item href="#array-1"/>
  3187. <item href="#array-2"/>
  3188. <item href="#array-2"/>
  3189. </SOAP-ENC:Array>
  3190. <SOAP-ENC:Array id="array-1" SOAP-ENC:arrayType="xsd:string[3]">
  3191. <item>r1c1</item>
  3192. <item>r1c2</item>
  3193. <item>r1c3</item>
  3194. </SOAP-ENC:Array>
  3195. <SOAP-ENC:Array id="array-2" SOAP-ENC:arrayType="xsd:string[2]">
  3196. <item>r2c1</item>
  3197. <item>r2c2</item>
  3198. </SOAP-ENC:Array>
  3199. </SOAP-ENV:Body>'''
  3200. x = parseSOAPRPC(xml)
  3201. self.assertEquals( x , [['r1c1', 'r1c2', 'r1c3'],
  3202. ['r2c1', 'r2c2'], ['r2c1', 'r2c2']])
  3203. xml = env % '''<SOAP-ENV:Body>
  3204. <SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[2,3]">
  3205. <item>r1c1</item>
  3206. <item>r1c2</item>
  3207. <item>r1c3</item>
  3208. <item>r2c1</item>
  3209. <item>r2c2</item>
  3210. <item>r2c3</item>
  3211. </SOAP-ENC:Array>
  3212. </SOAP-ENV:Body>'''
  3213. x = parseSOAPRPC(xml)
  3214. self.assertEquals( x , [['r1c1', 'r1c2', 'r1c3'], ['r2c1', 'r2c2', 'r2c3']])
  3215. xml = env % '''<SOAP-ENV:Body>
  3216. <SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[5]" SOAP-ENC:offset="[2]">
  3217. <item>The third element</item>
  3218. <item>The fourth element</item>
  3219. </SOAP-ENC:Array>
  3220. </SOAP-ENV:Body>'''
  3221. x = parseSOAPRPC(xml)
  3222. self.assertEquals( x , [None, None, 'The third element', 'The fourth element', None])
  3223. xml = env % '''<SOAP-ENV:Body>
  3224. <SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[,][4]">
  3225. <SOAP-ENC:Array href="#array-1" SOAP-ENC:position="[2]"/>
  3226. </SOAP-ENC:Array>
  3227. <SOAP-ENC:Array id="array-1" SOAP-ENC:arrayType="xsd:string[10,10]">
  3228. <item SOAP-ENC:position="[2,2]">Third row, third col</item>
  3229. <item SOAP-ENC:position="[7,2]">Eighth row, third col</item>
  3230. </SOAP-ENC:Array>
  3231. </SOAP-ENV:Body>'''
  3232. x = parseSOAPRPC(xml)
  3233. # Example using key data
  3234. def testKeyData(self):
  3235. xml = '''<?xml version="1.0" encoding="UTF-8"?>
  3236. <soap:Envelope xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/1999/XMLSchema" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance">
  3237. <soap:Body>
  3238. <xkms:RegisterResult xmlns:xkms="http://www.xkms.org/schema/xkms-2001-01-20">
  3239. <xkms:Result>Success</xkms:Result>
  3240. <xkms:Answer soapenc:arrayType="KeyBinding[1]">
  3241. <xkms:KeyBinding>
  3242. <xkms:Status>Valid</xkms:Status>
  3243. <xkms:KeyID>mailto:actzerotestkeyname</xkms:KeyID>
  3244. <dsig:KeyInfo>
  3245. <dsig:X509Data>
  3246. <dsig:X509Certificate>MIIDPjCCAqegAwIBAgIEOroMvDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVI3nlMkH84ZdPKIyz60sNcVEwJ8kF+B6ZVNimCF+r7BWgLi/Dolce5CpbfMMyexZ+UQEMADrc7331eYS891KXSDQx</dsig:X509Certificate>
  3247. </dsig:X509Data>
  3248. <dsig:KeyName>mailto:actzerotestkeyname</dsig:KeyName>
  3249. <dsig:KeyValue>
  3250. <dsig:RSAKeyValue>
  3251. <dsig:Modulus>wgmV2FY6MBKvtaMmCvCoNi/0hycZkiPKC2PXjRLJKFJ5wjNfF+vWsQQUXxOKUQnu
  3252. HjJqRkx90jJvnEzW3j9FlZFQcZTfJbE0v6BXhhSre2kZvkgcOERmDMeMs//oEA4u
  3253. epnedUwrkPzedWU9AL7c/oN7rk65UuPWf7V8c/4E9bc=</dsig:Modulus>
  3254. <dsig:Exponent>AQAB</dsig:Exponent>
  3255. </dsig:RSAKeyValue>
  3256. </dsig:KeyValue>
  3257. </dsig:KeyInfo>
  3258. </xkms:KeyBinding>
  3259. </xkms:Answer>
  3260. <xkms:Private>9GKuRC3ISwE9aEatzDKW0WIp+P/ufOvCxy9d5jVglLaRiTTIelHoGKCE6cDG62HYOu/3ebce6M7Z6LX6l1J9pB5PUx+f2DaMYYEGuOtNA7/ei5Ga/mibRBCehQIcN6FF6ESFOwAJBRLajj+orgYSy0u1sTCla0V4nSBrYA2H6lx8mD3qfDJ4hie7nU0YqZxy50F9f9UxXKIVSeutyIIBjWDDKv0kVpKy7OUerOaZXOW6HBohXuV74kXMUZu+MpLIkMHOrhJeo+edfhmeFuw4kCo5it6GkrOKrGs6zo1hSxWp7uuvKAPbvUrumC6sTsTxAUg4KTGq85IUnBTYI40Q9TZtzMcONtrWfIIF23/7NJyOmygBaFa4wFqHxe7j2gSWCQRv2fPwXo/AAJTeKwsUIY8OgmANHHbFVqJEeg27jbCuSaQFxWD7ms240YurTb55HBLk6JSufDl0CUbxoUgjrDB++gUb8oalroWDIb5NcZ94QER+HiTQfB11HcPDHvONnzk/n+iF+Mcri53ZbAButnfp2x87sh6RedeiUUWruYA4eonRq5+aj2I9cIrGLQaLemna1AQ+PyD2SMelBLukfR7GUc7zaSPjPJh2W/aYAJSyjM98g6ABNntdfhuf+6jRYnYFqSXZL1W1JPf92OMOfwfuXTE2K68sNwCRhcbHDLM=</xkms:Private>
  3261. </xkms:RegisterResult>
  3262. </soap:Body>
  3263. </soap:Envelope>'''
  3264. x = parseSOAPRPC(xml)
  3265. def testZeroLengthTypedArray(self):
  3266. """
  3267. Test that zero length typed arrays maintain thier type information when
  3268. converted to a SOAP message.
  3269. """
  3270. empty_int = typedArrayType(typed="int")
  3271. empty_int_message = buildSOAP( empty_int )
  3272. self.assertNotEquals( re.search("xsd:int\[0\]", empty_int_message),
  3273. None )
  3274. if __name__ == '__main__':
  3275. print """
  3276. NOTE: The 'testArray' test will fail because 'referenced' elements are
  3277. included in the return object. This is a known shortcoming of
  3278. the current version of SOAPpy.
  3279. All other tests should succeed.
  3280. """
  3281. unittest.main()