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.
 
 
 
 

3760 lines
136 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.request, urllib.parse, urllib.error
  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.assertTrue(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.assertTrue(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.assertTrue(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.assertEqual(y['Result']['Person']['age'], 49);
  108. self.assertEqual(y['Result']['Person']['height'], -5.5);
  109. else:
  110. self.assertEqual(y.Result.Person.age, 49);
  111. self.assertEqual(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.assertEqual(y['return'][0]['varString'], "West Virginia")
  153. self.assertEqual(y['return'][1]['varInt'], -641)
  154. self.assertEqual(y['return'][2]['varFloat'], 1.375)
  155. else:
  156. self.assertEqual(getattr(y,"return")[0].varString, "West Virginia")
  157. self.assertEqual(getattr(y,"return")[1].varInt, -641)
  158. self.assertEqual(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.assertEqual(y["return"][0]['string'], "West Virginia")
  197. self.assertEqual(y["return"][1]['int'], -641)
  198. self.assertEqual(y["return"][2]['float'], 1.375)
  199. else:
  200. self.assertEqual(getattr(y,"return")[0].string, "West Virginia")
  201. self.assertEqual(getattr(y,"return")[1].int, -641)
  202. self.assertEqual(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.assertEqual(y['return2'][1], "Hello")
  222. else:
  223. self.assertEqual(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.assertEqual(type(y.a), type([]))
  238. self.assertEqual(type(y.b), type(''))
  239. self.assertEqual(type(y._getItemAsList('a')), type([]))
  240. self.assertEqual(type(y._getItemAsList('b')), type([]))
  241. self.assertEqual(y.b, 'Goodbye')
  242. self.assertEqual(y.a, ['', 'Hello', '\'<&>"'])
  243. self.assertEqual(y._getItemAsList('b'), ['Goodbye'])
  244. self.assertEqual(y._getItemAsList('c'), [])
  245. self.assertEqual(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.assertEqual(y.a1, 'Hello')
  261. self.assertEqual(y.a3, 'Goodbye')
  262. self.assertFalse(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.assertEqual(y['Result']['Book']['author']['name'], "Henry Ford")
  290. self.assertEqual(y['Result']['Book']['author']['address']['web'], "http://www.henryford.com")
  291. self.assertEqual(y['Result']['Book']['author']['address']['pers']['name'], "Henry Ford")
  292. else:
  293. self.assertEqual(y.Result.Book.author.name, "Henry Ford")
  294. self.assertEqual(y.Result.Book.author.address.web, "http://www.henryford.com")
  295. self.assertEqual(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.assertEqual(y['Return'][0], 0)
  316. self.assertEqual(y['Return'][1], 1)
  317. self.assertEqual(y['Return'][2], -1)
  318. self.assertTrue(nearlyeq(y['Return'][3], 3853.33325))
  319. else:
  320. self.assertEqual(y.Return[0], 0)
  321. self.assertEqual(y.Return[1], 1)
  322. self.assertEqual(y.Return[2], -1)
  323. self.assertTrue(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.assertEqual(id(y.a), id(y.b))
  332. self.assertEqual(y.a, a)
  333. self.assertEqual(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 as e:
  349. self.assertTrue(isinstance(e, faultType))
  350. self.assertEqual(e.faultcode, '%s:VersionMismatch' % NS.ENV_T)
  351. self.assertFalse(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.assertEqual(a[id(x['Result'])][(None, 'name')], 'fred')
  462. else:
  463. self.assertEqual(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.assertEqual(z.__class__,faultType)
  496. self.assertEqual(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.assertEqual(type(z['Result']), type(''))
  504. else:
  505. self.assertEqual(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.assertEqual(x, z)
  511. def testStringArray(self):
  512. x = ["cayce", "asd", "buy"]
  513. y = buildSOAP(x)
  514. z = parseSOAPRPC(y)
  515. self.assertEqual(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.assertEqual(z.v1._elemsname, 'item')
  522. self.assertEqual(z.v1, x)
  523. else:
  524. self.assertEqual(z['v1']['_elemsname'], 'item')
  525. self.assertEqual(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.assertEqual(z.v1._elemsname, 'elementals')
  532. self.assertEqual(z.v1, x)
  533. else:
  534. self.assertEqual(z['v1']['_elemsname'], 'elementals')
  535. self.assertEqual(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.assertEqual(s['statenum'], 41)
  549. self.assertEqual(type(s['statenum']), type(0))
  550. else:
  551. self.assertEqual(s.statenum, 41)
  552. self.assertEqual(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.assertEqual(s['statenum'], 41, "NS one failed")
  566. self.assertEqual(type(s['statenum']), type(0))
  567. else:
  568. self.assertEqual(s.statenum, 41, "NS one failed")
  569. self.assertEqual(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.assertEqual(s['PriceAndVolume']['LastTradePrice'].strip(), "34.5")
  595. self.assertEqual(s['PriceAndVolume']['DayVolume'].strip(), "10000")
  596. else:
  597. self.assertEqual(s.PriceAndVolume.LastTradePrice.strip(), "34.5")
  598. self.assertEqual(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.assertEqual(s['param']['lowerBound'], 18)
  615. self.assertEqual(s['param']['upperBound'], 139)
  616. else:
  617. self.assertEqual(s.param.lowerBound, 18)
  618. self.assertEqual(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.assertEqual(s['param'][0], 12)
  639. self.assertEqual(s['param'][1], "Egypt")
  640. self.assertEqual(s['param'][2], 0)
  641. self.assertEqual(s['param'][3], -31)
  642. self.assertEqual(s['param1'], None)
  643. self.assertEqual(s['param2'], None)
  644. self.assertEqual(s['param3'], 7)
  645. else:
  646. self.assertEqual(s.param[0], 12)
  647. self.assertEqual(s.param[1], "Egypt")
  648. self.assertEqual(s.param[2], 0)
  649. self.assertEqual(s.param[3], -31)
  650. self.assertEqual(s.param1, None)
  651. self.assertEqual(s.param2, None)
  652. self.assertEqual(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.assertEqual(s.__class__, faultType)
  666. self.assertEqual(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.assertEqual(q[0], 5)
  697. self.assertEqual(q[1], 3)
  698. self.assertEqual(q[2], 2)
  699. self.assertEqual(q[3], 'monkey')
  700. self.assertEqual(q[4], 'cay')
  701. x = q[5]
  702. if config.simplify_objects:
  703. self.assertEqual(x['monkey'], 5)
  704. self.assertEqual(x['cat'], "hello")
  705. self.assertEqual(x['ferret'][0], 5)
  706. self.assertEqual(x['ferret'][3], 2)
  707. self.assertEqual(x['ferret'][5]['cow'], "moose")
  708. else:
  709. self.assertEqual(x.monkey, 5)
  710. self.assertEqual(x.cat, "hello")
  711. self.assertEqual(x.ferret[0], 5)
  712. self.assertEqual(x.ferret[3], 2)
  713. self.assertEqual(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.assertEqual(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.assertEqual( x['test'], z['test'] )
  727. else:
  728. self.assertEqual( 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.assertEqual( x.faultcode , z.faultcode)
  735. self.assertEqual( x.faultstring , z.faultstring)
  736. self.assertEqual( 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.assertEqual( y['t']['o']['t']['o']['t']['o']['t']['str'] , "two")
  750. else:
  751. self.assertEqual( 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.assertEqual( y['t']['o']['t']['o']['t']['o']['t']['str'] , "two")
  768. else:
  769. self.assertEqual( 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.assertEqual( m , z['msg'])
  778. else:
  779. self.assertEqual( 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 as 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.assertEqual( x , None)
  806. # Does SOAPProxy require a valid encoding?
  807. def testSOAPProxyEncoding(self):
  808. try:
  809. x = SOAPProxy('', encoding = 'gleck')
  810. except LookupError as 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.assertEqual( 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 as 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.assertEqual( x , None)
  828. def testEncodings(self):
  829. encodings = ('US-ASCII', 'ISO-8859-1', 'UTF-8', 'UTF-16')
  830. tests = ('A', '\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.assertEqual( y , t)
  836. tests = ('\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.assertEqual( y , t)
  846. tests = ('\u01a1', '\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.assertEqual( 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 list(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("instantiated a %s with a bad type (%s)" % \
  961. (repr(t), repr(type(i))))
  962. except AssertionError:
  963. raise
  964. except:
  965. pass
  966. # Now some things that should
  967. for i in ('hello', 'goodbye'):
  968. x = t(i)
  969. d = x._marshalData()
  970. if d != i:
  971. raise AssertionError("expected %s, got %s" % (i, d))
  972. y = buildSOAP(x)
  973. z = parseSOAPRPC(y)
  974. if z != i:
  975. raise AssertionError("expected %s, got %s" % (i, z))
  976. # ENTITIES, IDREFS, NMTOKENS
  977. for t in (ENTITIESType, IDREFSType, NMTOKENSType):
  978. # First some things that shouldn't be taken as the current type
  979. test = ({}, lambda x: x, ((),), ([],), [{}], [()])
  980. for i in test:
  981. try:
  982. t(i)
  983. raise AssertionError("instantiated a %s with a bad type (%s)" % \
  984. repr(t)).with_traceback(repr(type(i)))
  985. except AssertionError:
  986. raise
  987. except:
  988. pass
  989. # Now some things that should
  990. for i in ('hello', (), [], ('hello', 'goodbye'), ['aloha', 'guten_tag']):
  991. x = t(i)
  992. d = x._marshalData()
  993. if type(i) in (type(()), type([])):
  994. j = list(i)
  995. else:
  996. j = [i]
  997. k = ' '.join(j)
  998. if d != k:
  999. raise AssertionError("expected %s, got %s" % (k, d))
  1000. y = buildSOAP(x)
  1001. z = parseSOAPRPC(y)
  1002. if z != j:
  1003. raise AssertionError("expected %s, got %s" % (repr(j), repr(z)))
  1004. # uri, uriReference, anyURI
  1005. for t in (uriType, uriReferenceType, anyURIType):
  1006. # First some things that shouldn't be taken as the current type
  1007. test = (10, (), [], {})
  1008. for i in test:
  1009. try:
  1010. t(i)
  1011. raise AssertionError("instantiated a %s with a bad type (%s)" % \
  1012. t.__name__).with_traceback(repr(type(i)))
  1013. except AssertionError:
  1014. raise
  1015. except:
  1016. pass
  1017. # Now some things that should
  1018. for i in ('hello', 'goodbye', '!@#$%^&*()-_=+[{]}\|;:\'",<.>/?`~'):
  1019. x = t(i)
  1020. d = x._marshalData()
  1021. j = urllib.parse.quote(i)
  1022. if d != j:
  1023. raise AssertionError("expected %s, got %s" % (j, d))
  1024. y = buildSOAP(x)
  1025. z = parseSOAPRPC(y)
  1026. if z != i:
  1027. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  1028. # token First some things that shouldn't be valid because of type
  1029. test = (42, 3.14, (), [], {})
  1030. t = tokenType
  1031. for i in test:
  1032. try:
  1033. t(i)
  1034. raise AssertionError("instantiated a %s with a bad type (%s)" % (t.__name__, repr(i)))
  1035. except AssertionError:
  1036. raise
  1037. except AttributeError:
  1038. pass
  1039. # Now some things that shouldn't be valid because of content
  1040. test = (' hello', 'hello ', 'hel\nlo', 'hel\tlo', 'hel lo', ' \n \t ')
  1041. for i in test:
  1042. try:
  1043. t(i)
  1044. raise AssertionError("instantiated a %s with a bad value (%s)" % (t.__name__, repr(i)))
  1045. except AssertionError:
  1046. raise
  1047. except ValueError:
  1048. pass
  1049. # Now some things that should be valid
  1050. for i in ('', 'hello', 'hello'):
  1051. x = t(i)
  1052. d = x._marshalData()
  1053. if d != i:
  1054. raise AssertionError("expected %s, got %s" % (i, d))
  1055. y = buildSOAP(x)
  1056. z = parseSOAPRPC(y)
  1057. if z != i and i != '':
  1058. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  1059. #### CDATA, normalizedString
  1060. for t in (CDATAType, normalizedStringType):
  1061. # First some things that shouldn't be valid because of type
  1062. test = (42, 3.14, (), [], {})
  1063. for i in test:
  1064. try:
  1065. t(i)
  1066. raise AssertionError("instantiated a %s with a bad type (%s)" % \
  1067. (t.__name__, repr(i)))
  1068. except AssertionError:
  1069. raise
  1070. except AttributeError:
  1071. pass
  1072. # Now some things that shouldn't be valid because of content
  1073. test = ('hel\nlo', 'hel\rlo', 'hel\tlo', '\n\r\t')
  1074. for i in test:
  1075. try:
  1076. t(i)
  1077. raise AssertionError("instantiated a %s with a bad value (%s)" % \
  1078. (t.__name__, repr(i)))
  1079. except AssertionError:
  1080. raise
  1081. except ValueError:
  1082. pass
  1083. # Now some things that should be valid
  1084. for i in ('', 'hello', 'hello', 'hel lo'):
  1085. x = t(i)
  1086. d = x._marshalData()
  1087. if d != i:
  1088. raise AssertionError("expected %s, got %s" % (i, d))
  1089. y = buildSOAP(x)
  1090. z = parseSOAPRPC(y)
  1091. if z != i and i != '':
  1092. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  1093. #### boolean
  1094. # First some things that shouldn't be valid
  1095. test = (10, 'hello', (), [], {})
  1096. t = booleanType
  1097. for i in test:
  1098. try:
  1099. t(i)
  1100. raise AssertionError("instantiated a %s with a bad value (%s)" % (t.__name__, repr(i)))
  1101. except AssertionError:
  1102. raise
  1103. except:
  1104. pass
  1105. # Now some things that should
  1106. for i in ((0, 'false'), ('false', 'false'), (1, 'true'),
  1107. ('true', 'true'), (0.0, 'false'), (1.0, 'true')):
  1108. x = t(i[0])
  1109. d = x._marshalData()
  1110. if d != i[1]:
  1111. raise AssertionError("%s: expected %s, got %s" % (i[0], i[1], d))
  1112. y = buildSOAP(x)
  1113. z = parseSOAPRPC(y)
  1114. j = ('false', 'true')[z]
  1115. if j != i[1]:
  1116. raise AssertionError("%s: expected %s, got %s" % \
  1117. (i[0], repr(i[1]), repr(j)))
  1118. # Now test parsing, both valid and invalid
  1119. test = (('10', None), ('hello', None), ('false', 0), ('FALSE', 0),
  1120. (ws + 'false' + ws, 0), (ws + '0' + ws, 0),
  1121. ('0', 0), ('true', 1), ('TRUE', 1), ('1', 1),
  1122. (ws + 'true' + ws, 1), (ws + '1' + ws, 1))
  1123. for i in test:
  1124. try:
  1125. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  1126. if z != i[1]:
  1127. raise AssertionError("%s: expected %s, got %s" % \
  1128. (i[0], i[1], repr(z)))
  1129. except AssertionError:
  1130. raise
  1131. except:
  1132. if i[1] != None:
  1133. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  1134. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  1135. # Can we give it a name and no type?
  1136. #print
  1137. x = t(1, name = 'George', typed = 0)
  1138. #print "x=",x
  1139. y = buildSOAP(x)
  1140. #print "y=",y
  1141. z = parseSOAP(y)
  1142. #print "z=",z
  1143. test = 'true'
  1144. if z.George != test:
  1145. raise AssertionError("expected %s, got %s" % (repr(test), repr(z)))
  1146. # How about some attributes, set in various and sundry manners?
  1147. x = t(1, attrs = {'nonamespaceURI': 1})
  1148. x._setAttrs({(None, 'NonenamespaceURI'): 2,
  1149. ('http://some/namespace', 'namespaceURIattr1'): 3})
  1150. x._setAttr(('http://some/other/namespace', 'namespaceURIattr2'), 4)
  1151. self.assertEqual( x._getAttr('nonamespaceURI') , 1)
  1152. self.assertEqual( x._getAttr('NonenamespaceURI') , 2)
  1153. self.assertEqual( x._getAttr(('http://some/namespace',
  1154. 'namespaceURIattr1')) , 3)
  1155. self.assertEqual( x._getAttr(('http://some/other/namespace',
  1156. 'namespaceURIattr2')) , 4)
  1157. self.assertEqual( x._getAttr('non-extant attr') , None)
  1158. y = buildSOAP(x)
  1159. z = parseSOAPRPC(y)
  1160. self.assertEqual( z , 1)
  1161. #### decimal
  1162. # First some things that shouldn't be valid
  1163. test = ('hello', (), [], {})
  1164. t = decimalType
  1165. for i in test:
  1166. try:
  1167. t(i)
  1168. raise AssertionError("instantiated a %s with a bad type (%s)" % \
  1169. (t.__name__, repr(type(i))))
  1170. except AssertionError:
  1171. raise
  1172. except:
  1173. pass
  1174. # Now some things that should
  1175. for i in (10, 3.14, 23):
  1176. x = t(i)
  1177. d = x._marshalData()
  1178. if d != str(i):
  1179. raise AssertionError("expected %f, got %s" % (i, d))
  1180. y = buildSOAP(x)
  1181. z = parseSOAPRPC(y)
  1182. if z != i:
  1183. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  1184. # Now test parsing, both valid and invalid
  1185. test = (('hello', None), ('1.2.3', None), ('10', 10), ('10.', 10),
  1186. ('.1', .1), ('.1000000', .1), (ws + '10.4' + ws, 10.4))
  1187. for i in test:
  1188. try:
  1189. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  1190. if z != i[1]:
  1191. raise AssertionError("%s: expected %s, got %s" % \
  1192. (i[0], i[1], repr(z)))
  1193. except AssertionError:
  1194. raise
  1195. except:
  1196. if i[1] != None:
  1197. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  1198. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  1199. #### float
  1200. # First some things that shouldn't be valid
  1201. test = ('hello', (), [], {}, -3.402823466391E+38, 3.402823466391E+38)
  1202. t = floatType
  1203. for i in test:
  1204. try:
  1205. t(i)
  1206. raise AssertionError("instantiated a %s with a bad value (%s)" % \
  1207. (t.__name__, repr(i)))
  1208. except AssertionError:
  1209. raise
  1210. except ValueError:
  1211. pass
  1212. # Now some things that should
  1213. for i in (10, 3.14, 23, -3.4028234663852886E+38, 3.4028234663852886E+38):
  1214. x = t(i)
  1215. d = x._marshalData()
  1216. if not nearlyeq(float(d), i):
  1217. raise AssertionError("expected %f, got %s" % (i, d))
  1218. y = buildSOAP(x)
  1219. z = parseSOAPRPC(y)
  1220. if not nearlyeq(z, i):
  1221. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  1222. # Now test parsing, both valid and invalid
  1223. test = (('hello', None), ('1.2.3', None), ('10', 10), ('10.', 10),
  1224. ('.1', .1), ('.1000000', .1), (ws + '10.4' + ws, 10.4),
  1225. ('-3.402823466391E+38', None), ('3.402823466391E+38', None),
  1226. ('-3.4028234663852886E+38', -3.4028234663852886E+38),
  1227. ('3.4028234663852886E+38', 3.4028234663852886E+38))
  1228. for i in test:
  1229. try:
  1230. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  1231. if abs(z - i[1]) > 1e-6:
  1232. raise AssertionError("%s: expected %s, got %s" % \
  1233. (i[0], i[1], repr(z)))
  1234. except AssertionError:
  1235. raise
  1236. except:
  1237. if i[1] != None:
  1238. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  1239. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  1240. #### double
  1241. # First some things that shouldn't be valid
  1242. test = ('hello', (), [], {},
  1243. -1.7976931348623159E+308, 1.7976931348623159E+308)
  1244. t = doubleType
  1245. for i in test:
  1246. try:
  1247. t(i)
  1248. # Hide this error for now, cause it is a bug in python 2.0 and 2.1
  1249. if not (sys.version_info[0] == 2 and sys.version_info[1] <= 2
  1250. and i==1.7976931348623159E+308):
  1251. raise AssertionError("instantiated a double with a bad value (%s)" % repr(i))
  1252. except AssertionError:
  1253. raise
  1254. except ValueError:
  1255. pass
  1256. # Now some things that should
  1257. for i in (10, 3.14, 23, -1.79769313486E+308, 1.79769313486E+308):
  1258. x = t(i)
  1259. d = x._marshalData()
  1260. if not nearlyeq(float(d), i):
  1261. raise AssertionError("expected %s, got %s" % (i, str(x)))
  1262. y = buildSOAP(x)
  1263. z = parseSOAPRPC(y)
  1264. if not nearlyeq(z, i):
  1265. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  1266. # Now test parsing, both valid and invalid
  1267. test = (('hello', None), ('1.2.3', None), ('10', 10), ('10.', 10),
  1268. ('.1', .1), ('.1000000', .1), (ws + '10.4' + ws, 10.4),
  1269. ('-1.7976931348623159E+308', None), ('1.7976931348623158E+308', None),
  1270. ('-1.79769313486E+308', -1.79769313486E+308),
  1271. ('1.79769313486E+308', 1.79769313486E+308))
  1272. for i in test:
  1273. try:
  1274. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  1275. if abs(z - i[1]) > 1e-6:
  1276. raise AssertionError("%s: expected %s, got %s" % \
  1277. (i[0], i[1], repr(z)))
  1278. except AssertionError:
  1279. raise
  1280. except:
  1281. if i[1] != None:
  1282. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  1283. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  1284. #### hexBinary
  1285. x = ''
  1286. for i in range(256):
  1287. x += chr(i)
  1288. test = ('', x, 'hello')
  1289. t = hexBinaryType
  1290. l = []
  1291. for i in test:
  1292. l.append(hexBinaryType(i))
  1293. x = buildSOAP(l)
  1294. y = parseSOAPRPC(x)
  1295. for i in range(len(test)):
  1296. if test[i] != y[i]:
  1297. raise AssertionError("@ %d expected '%s', got '%s'" % \
  1298. (i, test[i], y[i]))
  1299. # Now test parsing, both valid and invalid
  1300. test = (('hello', None), ('6163 747A65726F', None), ('6163747A65726', None),
  1301. ('6163747A65726F', 'actzero'), (ws + '6163747A65726F' + ws, 'actzero'))
  1302. for i in test:
  1303. try:
  1304. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  1305. if z != i[1]:
  1306. raise AssertionError("%s: expected %s, got %s" % \
  1307. (i[0], i[1], repr(z)))
  1308. except AssertionError:
  1309. raise
  1310. except:
  1311. if i[1] != None:
  1312. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  1313. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  1314. #### base64Binary and base64
  1315. s = ''
  1316. for i in range(256):
  1317. s += chr(i)
  1318. for t in (base64BinaryType, base64Type):
  1319. # First some things that shouldn't be valid
  1320. test = ((), [], {}, lambda x: x)
  1321. for i in test:
  1322. try:
  1323. t(i)
  1324. raise AssertionError("instantiated a %s with a bad value (%s)" % \
  1325. (t.__name__, repr(i)))
  1326. except AssertionError:
  1327. raise
  1328. except AttributeError:
  1329. pass
  1330. # Now some things that should
  1331. test = ('', s, 'hello')
  1332. l = []
  1333. for i in test:
  1334. l.append(t(i))
  1335. x = buildSOAP(l)
  1336. y = parseSOAPRPC(x)
  1337. for i in range(len(test)):
  1338. if test[i] != y[i]:
  1339. raise AssertionError("@ %d expected '%s', got '%s'" % \
  1340. (i, test[i], y[i]))
  1341. # Now test parsing, both valid and invalid
  1342. test = (('hello', None), ('YWN0emVybw=', None),
  1343. ('YWN 0emVybw==', 'actzero'), ('YWN0emVybw==', 'actzero'),
  1344. (ws + 'YWN0emVybw==' + ws, 'actzero'))
  1345. for i in test:
  1346. try:
  1347. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  1348. if z != i[1]:
  1349. raise AssertionError("%s: expected %s, got %s" % \
  1350. (i[0], i[1], repr(z)))
  1351. except AssertionError:
  1352. raise
  1353. except:
  1354. if i[1] != None:
  1355. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  1356. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  1357. #### binary (uses s from above)
  1358. # First some check invalid encodings
  1359. try:
  1360. x = binaryType('hello', encoding = 'yellow')
  1361. raise AssertionError("created binary with invalid encoding")
  1362. except AssertionError:
  1363. raise
  1364. except:
  1365. pass
  1366. for t in ('hex', 'base64'):
  1367. # First some things that shouldn't be valid
  1368. test = ((), [], {}, lambda x: x)
  1369. for i in test:
  1370. try:
  1371. binaryType(i, encoding = t)
  1372. raise AssertionError("instantiated a %s binary with a bad value (%s)" % \
  1373. (e, repr(i)))
  1374. except AssertionError:
  1375. raise
  1376. except AttributeError:
  1377. pass
  1378. # Now some things that should
  1379. test = ('', s, 'hello')
  1380. l = []
  1381. for i in test:
  1382. l.append(binaryType(i, encoding = t))
  1383. x = buildSOAP(l)
  1384. y = parseSOAPRPC(x)
  1385. for i in range(len(test)):
  1386. if test[i] != y[i]:
  1387. raise AssertionError("@ %d expected '%s', got '%s'" % \
  1388. (i, test[i], y[i]))
  1389. # Now test parsing, both valid and invalid
  1390. if t == 'hex':
  1391. test = (('hello', None), ('6163 747A65726F', None),
  1392. ('6163747A65726', None), ('6163747A65726F', 'actzero'),
  1393. (ws + '6163747A65726F' + ws, 'actzero'))
  1394. else:
  1395. test = (('hello', None), ('YWN0emVybw=', None),
  1396. ('YWN 0emVybw==', 'actzero'), ('YWN0emVybw==', 'actzero'),
  1397. (ws + 'YWN0emVybw==' + ws, 'actzero'))
  1398. for i in test:
  1399. try:
  1400. z = parseSOAPRPC(self.build_xml(NS.XSD, 'binary', i[0],
  1401. ' encoding="%s"' % t))
  1402. if z != i[1]:
  1403. raise AssertionError("%s: expected %s, got %s" % \
  1404. (i[0], i[1], repr(z)))
  1405. except AssertionError:
  1406. raise
  1407. except:
  1408. if i[1] != None:
  1409. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  1410. (i[0], t, sys.exc_info()[0], sys.exc_info()[1]))
  1411. # Finally try an Array of binaries (with references!)
  1412. test = ('', s, 'hello')
  1413. l = []
  1414. for i in test:
  1415. l.append(binaryType(i, encoding = t))
  1416. l.append(l[1])
  1417. x = buildSOAP(l)
  1418. y = parseSOAPRPC(x)
  1419. for i in range(len(test)):
  1420. if test[i] != y[i]:
  1421. raise AssertionError("@ %d expected '%s', got '%s'" % \
  1422. (i, test[i], y[i]))
  1423. # Make sure the references worked
  1424. self.assertEqual( id(y[1]) , id(y[3]))
  1425. def badTest(self, t, data):
  1426. for i in data:
  1427. try:
  1428. t(i)
  1429. raise AssertionError("instantiated a %s with a bad value (%s)" % \
  1430. (t.__name__, repr(i)))
  1431. except AssertionError:
  1432. raise
  1433. except:
  1434. pass
  1435. def goodTest(self, t, data):
  1436. for i in data:
  1437. x = t(i[0])
  1438. d = x._marshalData()
  1439. if d != i[1]:
  1440. raise AssertionError("%s(%s): expected %s, got %s" % \
  1441. (t.__name__, repr(i[0]), i[1], d))
  1442. y = buildSOAP(x)
  1443. z = parseSOAPRPC(y)
  1444. if z != i[2]:
  1445. raise AssertionError("%s(%s): expected %s, got %s" % \
  1446. (t.__name__, repr(i[0]), repr(i[2]), repr(z)))
  1447. def parseTest(self, t, data):
  1448. for i in data:
  1449. try:
  1450. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4],
  1451. i[0]))
  1452. if z != i[1]:
  1453. raise AssertionError("%s(%s): expected %s, got %s" % \
  1454. (t.__name__, repr(i[0]), i[1], repr(z)))
  1455. except AssertionError:
  1456. raise
  1457. except:
  1458. if i[1] != N:
  1459. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  1460. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  1461. def allTests(self, t, baddata, gooddata, parsedata):
  1462. self.badTest(t, baddata)
  1463. self.goodTest(t, gooddata)
  1464. self.parseTest(t, parsedata)
  1465. # duration and timeDuration
  1466. def testTimeDuration(self):
  1467. baddata = \
  1468. (
  1469. 'hello',
  1470. ('hello',),
  1471. (-10, -10),
  1472. (-10, 0, -10),
  1473. (10.5, 10.5),
  1474. (0, 10.5, 0, 10.5, 0),
  1475. (1, 2, 3, 4, 5, 6, 7),
  1476. (1, 2, 'hello', 4, 5, 6),
  1477. (1, 2, 3.5, 4, 5, 6),
  1478. )
  1479. gooddata = \
  1480. (
  1481. (0, 'PT0S', (N, N, N, N, N, 0.0,)),
  1482. ((), 'PT0S', (N, N, N, N, N, 0.0,)),
  1483. ([], 'PT0S', (N, N, N, N, N, 0.0,)),
  1484. ((0.5,), 'PT0.5S', (N, N, N, N, N, 0.5,)),
  1485. (10, 'PT10S', (N, N, N, N, N, 10.0,)),
  1486. (-10, '-PT10S', (N, N, N, N, N, -10.0,)),
  1487. (10.5, 'PT10.5S', (N, N, N, N, N, 10.5,)),
  1488. ((10, 20), 'PT10M20S', (N, N, N, N, 10, 20.0)),
  1489. ((-10, 20), '-PT10M20S', (N, N, N, N, -10, 20.0)),
  1490. ((10, 0), 'PT10M', (N, N, N, N, 10, N)),
  1491. ((10, 0, 0), 'PT10H', (N, N, N, 10, N, N)),
  1492. ((10, 0, 0, 0), 'P10D', (N, N, 10, N, N, N)),
  1493. ((10, 0, 0, 0, 0), 'P10M', (N, 10, N, N, N, N)),
  1494. ((10, 0, 0, 0, 0, 0), 'P10Y', (10, N, N, N, N, N)),
  1495. ((-10, 0, 0, 0, 0, 0), '-P10Y', (-10, N, N, N, N, N)),
  1496. ((10, 0, 0, 0, 0, 20), 'P10YT20S', (10, N, N, N, N, 20.0,)),
  1497. ((1, 2, 3, 4, 5, 6.75), 'P1Y2M3DT4H5M6.75S',
  1498. (1, 2, 3, 4, 5, 6.75)),
  1499. ((-1, 2, 3, 4, 5, 6.75), '-P1Y2M3DT4H5M6.75S',
  1500. (-1, 2, 3, 4, 5, 6.75)),
  1501. ((1, 2, 3, 10, 30, 0), 'P1Y2M3DT10H30M',
  1502. (1, 2, 3, 10, 30, N)),
  1503. ((1e6, 2e6, 3e6, 4e6, 5e6, 6.7e6),
  1504. 'P1000000Y2000000M3000000DT4000000H5000000M6700000S',
  1505. (1e6, 2e6, 3e6, 4e6, 5e6, 6.7e6)),
  1506. ((1347, 0, N, 0, 0), 'P1347M', (N, 1347, N, N, N, N)),
  1507. ((-1347, 0, 0, 0, N), '-P1347M', (N, -1347, N, N, N, N)),
  1508. ((1e15, 0, 0, 0, 0), 'P1000000000000000M',
  1509. (N, 1000000000000000, N, N, N, N)),
  1510. ((-1e15, 0, 0, 0, 0), '-P1000000000000000M',
  1511. (N, -1000000000000000, N, N, N, N)),
  1512. ((1000000000000000, 0, 0, 0, 0), 'P1000000000000000M',
  1513. (N, 1000000000000000, N, N, N, N)),
  1514. ((-1000000000000000, 0, 0, 0, 0), '-P1000000000000000M',
  1515. (N, -1000000000000000, N, N, N, N)),
  1516. )
  1517. parsedata = (
  1518. ('hello', N),
  1519. ('P T0S', N),
  1520. ('P10.5Y10.5M', N),
  1521. ('P1Y2MT', N),
  1522. ('PT0S', (N, N, N, N, N, 0,)),
  1523. ('P10Y', (10, N, N, N, N, N)),
  1524. (ws + 'P10M' + ws, (N, 10, N, N, N, N)),
  1525. ('P0Y1347M', (0, 1347, N, N, N, N)),
  1526. ('P0Y1347M0D', (0, 1347, 0, N, N, N)),
  1527. ('P0MT0M', (N, 0, N, N, 0, N)),
  1528. )
  1529. for t in (durationType, timeDurationType):
  1530. self.allTests(t, baddata, gooddata, parsedata)
  1531. # dateTime, timeInstant, and timePeriod
  1532. def testTimePeriod(self):
  1533. baddata = \
  1534. (
  1535. 'hello',
  1536. ('hello',),
  1537. (1, 2, 3, 4, 5),
  1538. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  1539. (1, 2, 3, 4, 5, 'hello'),
  1540. (1, 2.5, 3, 4, 5, 6),
  1541. (1, 0, 3, 4, 5, 6),
  1542. (1, 13, 3, 4, 5, 6),
  1543. (1, 1, 0, 4, 5, 6),
  1544. (1, 1, 32, 4, 5, 6),
  1545. (1, 2, 29, 4, 5, 6),
  1546. (0, 2, 30, 4, 5, 6),
  1547. (100, 2, 29, 4, 5, 6),
  1548. (1, 2, 3, -1, 5, 6),
  1549. (1, 2, 3, 24, 5, 6),
  1550. (1, 2, 3, 4, -1, 6),
  1551. (1, 2, 3, 4, 60, 6),
  1552. (1, 2, 3, 4, 5, -1),
  1553. (1, 2, 3, 4, 5, 61),
  1554. (1, 3, 32, 4, 5, 6),
  1555. (1, 4, 31, 4, 5, 6),
  1556. (1, 5, 32, 4, 5, 6),
  1557. (1, 6, 31, 4, 5, 6),
  1558. (1, 7, 32, 4, 5, 6),
  1559. (1, 8, 32, 4, 5, 6),
  1560. (1, 9, 31, 4, 5, 6),
  1561. (1, 10, 32, 4, 5, 6),
  1562. (1, 11, 31, 4, 5, 6),
  1563. (1, 12, 32, 4, 5, 6),
  1564. )
  1565. gooddata = \
  1566. (
  1567. (1, '1970-01-01T00:00:01Z', (1970, 1, 1, 0, 0, 1.0)),
  1568. (1.5, '1970-01-01T00:00:01.5Z', (1970, 1, 1, 0, 0, 1.5)),
  1569. ((-1, 2, 3, 4, 5, 6), '-0001-02-03T04:05:06Z',
  1570. (-1, 2, 3, 4, 5, 6.0)),
  1571. ((1, 2, 3, 4, 5, 6), '0001-02-03T04:05:06Z',
  1572. (1, 2, 3, 4, 5, 6.0)),
  1573. ((10, 2, 3, 4, 5, 6), '0010-02-03T04:05:06Z',
  1574. (10, 2, 3, 4, 5, 6.0)),
  1575. ((100, 2, 3, 4, 5, 6), '0100-02-03T04:05:06Z',
  1576. (100, 2, 3, 4, 5, 6.0)),
  1577. ((1970, 2, 3, 4, 5, 6), '1970-02-03T04:05:06Z',
  1578. (1970, 2, 3, 4, 5, 6.0)),
  1579. ((-1970, 2, 3, 4, 5, 6), '-1970-02-03T04:05:06Z',
  1580. (-1970, 2, 3, 4, 5, 6.0)),
  1581. ((1970, 2.0, 3.0, 4, 5, 6.875), '1970-02-03T04:05:06.875Z',
  1582. (1970, 2, 3, 4, 5, 6.875)),
  1583. ((11990, 1, 2, 3, 4, 5.25, 0, 0, 0),
  1584. '11990-01-02T03:04:05.25Z',
  1585. (11990, 1, 2, 3, 4, 5.25)),
  1586. ((1e15, 1, 2, 3, 4, 5.25, 0, 0, 0),
  1587. '1000000000000000-01-02T03:04:05.25Z',
  1588. (1e15, 1, 2, 3, 4, 5.25)),
  1589. ((-1e15, 1, 2, 3, 4, 5.25, 0, 0, 0),
  1590. '-1000000000000000-01-02T03:04:05.25Z',
  1591. (-1e15, 1, 2, 3, 4, 5.25)),
  1592. ((1000000000000000, 1, 2, 3, 4, 5.25, 0, 0, 0),
  1593. '1000000000000000-01-02T03:04:05.25Z',
  1594. (1e15, 1, 2, 3, 4, 5.25)),
  1595. ((-1000000000000000, 1, 2, 3, 4, 5.25, 0, 0, 0),
  1596. '-1000000000000000-01-02T03:04:05.25Z',
  1597. (-1e15, 1, 2, 3, 4, 5.25)),
  1598. )
  1599. parsedata = \
  1600. (
  1601. # Some strings that won't match the r.e.
  1602. ('hello', N),
  1603. ('1970 -01 -01T00:00:01Z', N),
  1604. ('0001-02-03t07:08:23Z', N),
  1605. # Invalid ranges
  1606. ('2001-00-03T07:08:23Z', N),
  1607. ('2001-13-03T07:08:23Z', N),
  1608. ('2001-02-00T07:08:23Z', N),
  1609. ('2001-02-29T07:08:23Z', N),
  1610. ('2000-02-30T07:08:23Z', N),
  1611. ('1900-02-29T07:08:23Z', N),
  1612. ('2001-02-03T24:08:23Z', N),
  1613. ('2001-02-03T04:60:23Z', N),
  1614. ('2001-02-03T04:05:61Z', N),
  1615. ('2001-01-32T04:05:06Z', N),
  1616. ('2001-03-32T04:05:06Z', N),
  1617. ('2001-04-31T04:05:06Z', N),
  1618. ('2001-05-32T04:05:06Z', N),
  1619. ('2001-06-31T04:05:06Z', N),
  1620. ('2001-07-32T04:05:06Z', N),
  1621. ('2001-08-32T04:05:06Z', N),
  1622. ('2001-09-31T04:05:06Z', N),
  1623. ('2001-10-32T04:05:06Z', N),
  1624. ('2001-11-31T04:05:06Z', N),
  1625. ('2001-12-32T04:05:06Z', N),
  1626. # Whitespace
  1627. (ws + '1970-01-01T00:00:00Z' + ws, (1970, 1, 1, 0, 0, 0)),
  1628. # No timezones
  1629. ('11971-02-03T04:05:06.125', (11971, 2, 3, 4, 5, 6.125)),
  1630. ('1971-02-03T04:05:06.125', (1971, 2, 3, 4, 5, 6.125)),
  1631. ('-1971-02-03T04:05:06.125', (-1971, 2, 3, 4, 5, 6.125)),
  1632. # Non-zulu
  1633. ('11971-02-03T04:05:06.125-07:08', (11971, 2, 3, 11, 13, 6.125)),
  1634. ('11971-02-03T04:05:06.125+07:08', (11971, 2, 2, 20, 57, 6.125)),
  1635. ('-11971-02-03T04:05:06.125-07:08', (-11971, 2, 3, 11, 13, 6.125)),
  1636. ('-11971-02-03T04:05:06.125+07:08', (-11971, 2, 2, 20, 57, 6.125)),
  1637. ('1971-02-03T04:05:06.125-07:08', (1971, 2, 3, 11, 13, 6.125)),
  1638. ('1971-02-03T04:05:06.125+07:08', (1971, 2, 2, 20, 57, 6.125)),
  1639. ('-1971-02-03T04:05:06.125-07:08', (-1971, 2, 3, 11, 13, 6.125)),
  1640. ('-1971-02-03T04:05:06.125+07:08', (-1971, 2, 2, 20, 57, 6.125)),
  1641. # Edgepoints (ranges)
  1642. ('2001-01-03T07:08:09Z', (2001, 1, 3, 7, 8, 9)),
  1643. ('2001-12-03T07:08:09Z', (2001, 12, 3, 7, 8, 9)),
  1644. ('2001-02-01T07:08:09Z', (2001, 2, 1, 7, 8, 9)),
  1645. ('2001-02-28T07:08:09Z', (2001, 2, 28, 7, 8, 9)),
  1646. ('2000-02-29T07:08:09Z', (2000, 2, 29, 7, 8, 9)),
  1647. ('1900-02-28T07:08:09Z', (1900, 2, 28, 7, 8, 9)),
  1648. ('2001-02-03T00:08:09Z', (2001, 2, 3, 0, 8, 9)),
  1649. ('2001-02-03T23:08:09Z', (2001, 2, 3, 23, 8, 9)),
  1650. ('2001-02-03T04:00:09Z', (2001, 2, 3, 4, 0, 9)),
  1651. ('2001-02-03T04:59:09Z', (2001, 2, 3, 4, 59, 9)),
  1652. ('2001-02-03T04:05:00Z', (2001, 2, 3, 4, 5, 0)),
  1653. ('2001-02-03T04:05:60.9Z', (2001, 2, 3, 4, 5, 60.9)),
  1654. ('2001-01-31T04:05:06Z', (2001, 1, 31, 4, 5, 6)),
  1655. ('2001-03-31T04:05:06Z', (2001, 3, 31, 4, 5, 6)),
  1656. ('2001-04-30T04:05:06Z', (2001, 4, 30, 4, 5, 6)),
  1657. ('2001-05-31T04:05:06Z', (2001, 5, 31, 4, 5, 6)),
  1658. ('2001-06-30T04:05:06Z', (2001, 6, 30, 4, 5, 6)),
  1659. ('2001-07-31T04:05:06Z', (2001, 7, 31, 4, 5, 6)),
  1660. ('2001-08-31T04:05:06Z', (2001, 8, 31, 4, 5, 6)),
  1661. ('2001-09-30T04:05:06Z', (2001, 9, 30, 4, 5, 6)),
  1662. ('2001-10-31T04:05:06Z', (2001, 10, 31, 4, 5, 6)),
  1663. ('2001-11-30T04:05:06Z', (2001, 11, 30, 4, 5, 6)),
  1664. ('2001-12-31T04:05:06Z', (2001, 12, 31, 4, 5, 6)),
  1665. # Edgepoints (crossing boundaries)
  1666. ('0001-01-01T07:08:23+07:08', (1, 1, 1, 0, 0, 23)),
  1667. ('0001-01-01T07:07:42+07:08', (0, 12, 31, 23, 59, 42)),
  1668. ('-0004-01-01T07:07:42+07:08', (-5, 12, 31, 23, 59, 42)),
  1669. ('2001-03-01T07:07:42+07:08', (2001, 2, 28, 23, 59, 42)),
  1670. ('2000-03-01T07:07:42+07:08', (2000, 2, 29, 23, 59, 42)),
  1671. ('1900-03-01T07:07:42+07:08', (1900, 2, 28, 23, 59, 42)),
  1672. )
  1673. for t in (dateTimeType, timeInstantType, timePeriodType):
  1674. self.allTests(t, baddata, gooddata, parsedata)
  1675. # recurringInstant
  1676. def testRecurringInstant(self):
  1677. baddata = \
  1678. (
  1679. 'hello',
  1680. ('hello',),
  1681. (1, 2, N, 3, 4, 5),
  1682. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  1683. (1, 2, 3, 4, 5, 'hello'),
  1684. (1, 2, 3.5, 4, 5, 6),
  1685. )
  1686. gooddata = \
  1687. (
  1688. (1, '1970-01-01T00:00:01Z', (1970, 1, 1, 0, 0, 1.0)),
  1689. (1.5, '1970-01-01T00:00:01.5Z', (1970, 1, 1, 0, 0, 1.5)),
  1690. (1e9, '2001-09-09T01:46:40Z', (2001, 9, 9, 1, 46, 40.0)),
  1691. ((1, 1, 2, 3, 4, 5), '-01-01-02T03:04:05Z',
  1692. (1, 1, 2, 3, 4, 5)),
  1693. ((-1, 1, 2, 3, 4, 5), '--01-01-02T03:04:05Z',
  1694. (-1, 1, 2, 3, 4, 5)),
  1695. ((10, 1, 2, 3, 4, 5), '-10-01-02T03:04:05Z',
  1696. (10, 1, 2, 3, 4, 5)),
  1697. ((-10, 1, 2, 3, 4, 5), '--10-01-02T03:04:05Z',
  1698. (-10, 1, 2, 3, 4, 5)),
  1699. ((100, 1, 2, 3, 4, 5), '0100-01-02T03:04:05Z',
  1700. (100, 1, 2, 3, 4, 5)),
  1701. ((-100, 1, 2, 3, 4, 5), '-0100-01-02T03:04:05Z',
  1702. (-100, 1, 2, 3, 4, 5)),
  1703. ((1970, 1, 2, 3, 4, 5), '1970-01-02T03:04:05Z',
  1704. (1970, 1, 2, 3, 4, 5)),
  1705. ((1970, 1, 2, 3, 4.0, 5.25), '1970-01-02T03:04:05.25Z',
  1706. (1970, 1, 2, 3, 4, 5.25)),
  1707. ((11990, 1, 2, 3, 4, 5.25), '11990-01-02T03:04:05.25Z',
  1708. (11990, 1, 2, 3, 4, 5.25)),
  1709. ((1e15, 1, 2, 3, 4, 5.25),
  1710. '1000000000000000-01-02T03:04:05.25Z',
  1711. (1e15, 1, 2, 3, 4, 5.25)),
  1712. ((-1e15, 1, 2, 3, 4, 5.25),
  1713. '-1000000000000000-01-02T03:04:05.25Z',
  1714. (-1e15, 1, 2, 3, 4, 5.25)),
  1715. ((N, 1, 2, 3, 4, 5.25), '---01-02T03:04:05.25Z',
  1716. (N, 1, 2, 3, 4, 5.25)),
  1717. ((N, N, 2, 3, 4, 5.25, 0, 0, 0), '-----02T03:04:05.25Z',
  1718. (N, N, 2, 3, 4, 5.25)),
  1719. ((N, N, -2, 3, 4, 5.25, 0, 0, 0), '------02T03:04:05.25Z',
  1720. (N, N, -2, 3, 4, 5.25)),
  1721. ((N, N, N, 3, 4, 5.25), '------T03:04:05.25Z',
  1722. (N, N, N, 3, 4, 5.25)),
  1723. ((N, N, N, N, 4, 5.25, 0, 0, 0), '------T-:04:05.25Z',
  1724. (N, N, N, N, 4, 5.25)),
  1725. ((N, N, N, N, N, 5.25), '------T-:-:05.25Z',
  1726. (N, N, N, N, N, 5.25)),
  1727. ((N, N, N, N, N, -5.25), '-------T-:-:05.25Z',
  1728. (N, N, N, N, N, -5.25)),
  1729. ((N, N, N, N, N, N, 0, 0, 0), '------T-:-:-Z',
  1730. (N, N, N, N, N, N)),
  1731. ((N, N, N, N, N, N, N), '------T-:-:-Z',
  1732. (N, N, N, N, N, N)),
  1733. ((N, N, N, N, N, N, N, N),
  1734. '------T-:-:-Z', (N, N, N, N, N, N)),
  1735. ((N, N, N, N, N, N, N, N, N),
  1736. '------T-:-:-Z', (N, N, N, N, N, N)),
  1737. )
  1738. parsedata = \
  1739. (
  1740. # Some strings that won't match the r.e.
  1741. ('hello', N),
  1742. ('1970 -01 -01T00:00:01Z', N),
  1743. ('0001-01-01t07:08:23+07:08', N),
  1744. # Invalid ranges
  1745. ('2001-00-03T07:08:23Z', N),
  1746. ('2001-13-03T07:08:23Z', N),
  1747. ('2001-02-00T07:08:23Z', N),
  1748. ('2001-02-29T07:08:23Z', N),
  1749. ('2000-02-30T07:08:23Z', N),
  1750. ('1900-02-29T07:08:23Z', N),
  1751. ('2001-02-03T24:08:23Z', N),
  1752. ('2001-02-03T04:60:23Z', N),
  1753. ('2001-02-03T04:05:61Z', N),
  1754. ('2001-01-32T04:05:06Z', N),
  1755. ('2001-03-32T04:05:06Z', N),
  1756. ('2001-04-31T04:05:06Z', N),
  1757. ('2001-05-32T04:05:06Z', N),
  1758. ('2001-06-31T04:05:06Z', N),
  1759. ('2001-07-32T04:05:06Z', N),
  1760. ('2001-08-32T04:05:06Z', N),
  1761. ('2001-09-31T04:05:06Z', N),
  1762. ('2001-10-32T04:05:06Z', N),
  1763. ('2001-11-31T04:05:06Z', N),
  1764. ('2001-12-32T04:05:06Z', N),
  1765. # Whitespace
  1766. (ws + '1970-01-01T00:00:01Z' + ws, (1970, 1, 1, 0, 0, 1)),
  1767. # No timezones
  1768. ('11971-02-03T04:05:06.125', (11971, 2, 3, 4, 5, 6.125)),
  1769. ('-11971-02-03T04:05:06.125', (-11971, 2, 3, 4, 5, 6.125)),
  1770. ('1971-02-03T04:05:06.125', (1971, 2, 3, 4, 5, 6.125)),
  1771. ('-1971-02-03T04:05:06.125', (-1971, 2, 3, 4, 5, 6.125)),
  1772. ('-71-02-03T04:05:06.125', (71, 2, 3, 4, 5, 6.125)),
  1773. ('--71-02-03T04:05:06.125', (-71, 2, 3, 4, 5, 6.125)),
  1774. ('---02-03T04:05:06.125', (N, 2, 3, 4, 5, 6.125)),
  1775. ('----02-03T04:05:06.125', (N, -2, 3, 4, 5, 6.125)),
  1776. ('-----03T04:05:06.125', (N, N, 3, 4, 5, 6.125)),
  1777. ('------03T04:05:06.125', (N, N, -3, 4, 5, 6.125)),
  1778. ('------T04:05:06.125', (N, N, N, 4, 5, 6.125)),
  1779. ('-------T04:05:06.125', (N, N, N, -4, 5, 6.125)),
  1780. ('------T-:05:06.125', (N, N, N, N, 5, 6.125)),
  1781. ('-------T-:05:06.125', (N, N, N, N, -5, 6.125)),
  1782. ('------T-:-:06.125', (N, N, N, N, N, 6.125)),
  1783. ('-------T-:-:06.125', (N, N, N, N, N, -6.125)),
  1784. ('------T-:-:-', (N, N, N, N, N, N)),
  1785. ('-------T-:-:-', (N, N, N, N, N, N)),
  1786. # Non-zulu
  1787. ('11971-02-03T04:05:06.125-07:08', (11971, 2, 3, 11, 13, 6.125)),
  1788. ('11971-02-03T04:05:06.125+07:08', (11971, 2, 2, 20, 57, 6.125)),
  1789. ('-11971-02-03T04:05:06.125-07:08', (-11971, 2, 3, 11, 13, 6.125)),
  1790. ('-11971-02-03T04:05:06.125+07:08', (-11971, 2, 2, 20, 57, 6.125)),
  1791. ('1971-02-03T04:05:06.125-07:08', (1971, 2, 3, 11, 13, 6.125)),
  1792. ('1971-02-03T04:05:06.125+07:08', (1971, 2, 2, 20, 57, 6.125)),
  1793. ('-1971-02-03T04:05:06.125-07:08', (-1971, 2, 3, 11, 13, 6.125)),
  1794. ('-1971-02-03T04:05:06.125+07:08', (-1971, 2, 2, 20, 57, 6.125)),
  1795. ('-71-02-03T04:05:06.125-07:08', (71, 2, 3, 11, 13, 6.125)),
  1796. ('-71-02-03T04:05:06.125+07:08', (71, 2, 2, 20, 57, 6.125)),
  1797. ('--71-02-03T04:05:06.125-07:08', (-71, 2, 3, 11, 13, 6.125)),
  1798. ('--71-02-03T04:05:06.125+07:08', (-71, 2, 2, 20, 57, 6.125)),
  1799. ('---02-03T04:05:06.125-07:08', (N, 2, 3, 11, 13, 6.125)),
  1800. ('---02-03T04:05:06.125+07:08', (N, 2, 2, 20, 57, 6.125)),
  1801. ('----02-03T04:05:06.125-07:08', (N, -2, 3, 11, 13, 6.125)),
  1802. ('----02-03T04:05:06.125+07:08', (N, -2, 2, 20, 57, 6.125)),
  1803. ('-----03T04:05:06.125-07:08', (N, N, 3, 11, 13, 6.125)),
  1804. ('-----03T04:05:06.125+07:08', (N, N, 2, 20, 57, 6.125)),
  1805. ('------03T04:05:06.125-07:08', (N, N, -3, 11, 13, 6.125)),
  1806. ('------03T04:05:06.125+07:08', (N, N, -4, 20, 57, 6.125)),
  1807. ('------T04:05:06.125-07:08', (N, N, N, 11, 13, 6.125)),
  1808. ('------T04:05:06.125+07:08', (N, N, N, -4, 57, 6.125)),
  1809. ('-------T04:05:06.125-07:08', (N, N, N, 3, 13, 6.125)),
  1810. ('-------T04:05:06.125+07:08', (N, N, N, -12, 57, 6.125)),
  1811. ('------T-:05:06.125-07:08', (N, N, N, N, 433, 6.125)),
  1812. ('------T-:05:06.125+07:08', (N, N, N, N, -423, 6.125)),
  1813. ('-------T-:05:06.125-07:08', (N, N, N, N, 423, 6.125)),
  1814. ('-------T-:05:06.125+07:08', (N, N, N, N, -433, 6.125)),
  1815. ('------T-:-:06.125-07:08', (N, N, N, N, 428, 6.125)),
  1816. ('------T-:-:06.125+07:08', (N, N, N, N, -428, 6.125)),
  1817. ('-------T-:-:06.125-07:08', (N, N, N, N, 427, 53.875)),
  1818. ('-------T-:-:06.125+07:08', (N, N, N, N, -429, 53.875)),
  1819. ('------T-:-:--07:08', (N, N, N, N, 428, 0)),
  1820. ('------T-:-:-+07:08', (N, N, N, N, -428, 0)),
  1821. ('-------T-:-:--07:08', (N, N, N, N, 428, 0)),
  1822. ('-------T-:-:-+07:08', (N, N, N, N, -428, 0)),
  1823. # Edgepoints (ranges)
  1824. ('2001-01-03T07:08:09Z', (2001, 1, 3, 7, 8, 9)),
  1825. ('2001-12-03T07:08:09Z', (2001, 12, 3, 7, 8, 9)),
  1826. ('2001-02-01T07:08:09Z', (2001, 2, 1, 7, 8, 9)),
  1827. ('2001-02-28T07:08:09Z', (2001, 2, 28, 7, 8, 9)),
  1828. ('2000-02-29T07:08:09Z', (2000, 2, 29, 7, 8, 9)),
  1829. ('1900-02-28T07:08:09Z', (1900, 2, 28, 7, 8, 9)),
  1830. ('2001-02-03T00:08:09Z', (2001, 2, 3, 0, 8, 9)),
  1831. ('2001-02-03T23:08:09Z', (2001, 2, 3, 23, 8, 9)),
  1832. ('2001-02-03T04:00:09Z', (2001, 2, 3, 4, 0, 9)),
  1833. ('2001-02-03T04:59:09Z', (2001, 2, 3, 4, 59, 9)),
  1834. ('2001-02-03T04:05:00Z', (2001, 2, 3, 4, 5, 0)),
  1835. ('2001-02-03T04:05:60.9Z', (2001, 2, 3, 4, 5, 60.9)),
  1836. ('2001-01-31T04:05:06Z', (2001, 1, 31, 4, 5, 6)),
  1837. ('2001-03-31T04:05:06Z', (2001, 3, 31, 4, 5, 6)),
  1838. ('2001-04-30T04:05:06Z', (2001, 4, 30, 4, 5, 6)),
  1839. ('2001-05-31T04:05:06Z', (2001, 5, 31, 4, 5, 6)),
  1840. ('2001-06-30T04:05:06Z', (2001, 6, 30, 4, 5, 6)),
  1841. ('2001-07-31T04:05:06Z', (2001, 7, 31, 4, 5, 6)),
  1842. ('2001-08-31T04:05:06Z', (2001, 8, 31, 4, 5, 6)),
  1843. ('2001-09-30T04:05:06Z', (2001, 9, 30, 4, 5, 6)),
  1844. ('2001-10-31T04:05:06Z', (2001, 10, 31, 4, 5, 6)),
  1845. ('2001-11-30T04:05:06Z', (2001, 11, 30, 4, 5, 6)),
  1846. ('2001-12-31T04:05:06Z', (2001, 12, 31, 4, 5, 6)),
  1847. # Edgepoints (crossing boundaries)
  1848. ('0001-01-01T07:08:23+07:08', (1, 1, 1, 0, 0, 23)),
  1849. ('0001-01-01T07:07:42+07:08', (0, 12, 31, 23, 59, 42)),
  1850. ('-0004-01-01T07:07:42+07:08', (-5, 12, 31, 23, 59, 42)),
  1851. ('2001-03-01T07:07:42+07:08', (2001, 2, 28, 23, 59, 42)),
  1852. ('2000-03-01T07:07:42+07:08', (2000, 2, 29, 23, 59, 42)),
  1853. ('1900-03-01T07:07:42+07:08', (1900, 2, 28, 23, 59, 42)),
  1854. ('---03-01T07:07:42+07:08', (N, 2, 28, 23, 59, 42)),
  1855. )
  1856. for t in (recurringInstantType,):
  1857. self.allTests(t, baddata, gooddata, parsedata)
  1858. def testTime(self):
  1859. baddata = \
  1860. (
  1861. 'hello',
  1862. ('hello',),
  1863. (1, 2, 3, 4, 5),
  1864. (1, 2, 3, 4, 5, 6, 7, 8),
  1865. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  1866. (1, 2, 'hello'),
  1867. (1, 2.5, 3),
  1868. (25, 0, 0),
  1869. (1, 60, 0),
  1870. (1, 0, 61),
  1871. )
  1872. gooddata = \
  1873. (
  1874. (1, '00:00:01Z', (0, 0, 1.0)),
  1875. (1.5, '00:00:01.5Z', (0, 0, 1.5)),
  1876. (3661.5, '01:01:01.5Z', (1, 1, 1.5)),
  1877. (86399.75, '23:59:59.75Z', (23, 59, 59.75)),
  1878. ((1,), '01:00:00Z', (1, 0, 0)),
  1879. ((1, 2), '01:02:00Z', (1, 2, 0)),
  1880. ((10, 20.0, 30), '10:20:30Z', (10, 20, 30.0)),
  1881. )
  1882. parsedata = \
  1883. (
  1884. # Some strings that won't match the r.e.
  1885. ('hello', N),
  1886. ('00 00:01Z', N),
  1887. ('07:O8:23Z', N),
  1888. # Invalid ranges
  1889. ('24:08:23Z', N),
  1890. ('04:60:23Z', N),
  1891. ('04:05:61Z', N),
  1892. # Whitespace
  1893. (ws + '00:00:01Z' + ws, (0, 0, 1)),
  1894. # No timezones
  1895. ('04:05:06.125', (4, 5, 6.125)),
  1896. # Non-zulu
  1897. ('04:05:06.125-07:08', (11, 13, 6.125)),
  1898. ('04:05:06.125+07:08', (-4, 57, 6.125)),
  1899. # Edgepoints (ranges)
  1900. ('00:08:09Z', (0, 8, 9)),
  1901. ('23:08:09Z', (23, 8, 9)),
  1902. ('04:00:09Z', (4, 0, 9)),
  1903. ('04:59:09Z', (4, 59, 9)),
  1904. ('04:05:00Z', (4, 5, 0)),
  1905. ('04:05:60.9Z', (4, 5, 60.9)),
  1906. # Edgepoints (crossing boundaries)
  1907. ('07:08:23+07:08', (0, 0, 23)),
  1908. ('07:07:42+07:08', (-1, 59, 42)),
  1909. )
  1910. for t in (timeType,):
  1911. self.allTests(t, baddata, gooddata, parsedata)
  1912. def testDate(self):
  1913. baddata = \
  1914. (
  1915. 'hello',
  1916. ('hello',),
  1917. (1, 2, 3, 4, 5),
  1918. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  1919. (1, 2, 3, 4, 5, 'hello'),
  1920. (1, 2.5, 3, 4, 5, 6),
  1921. (1, 2, 3.5),
  1922. (1, 0, 3),
  1923. (1, 13, 3),
  1924. (1, 1, 0),
  1925. (1, 1, 32),
  1926. (1, 2, 29),
  1927. (0, 2, 30),
  1928. (100, 2, 29),
  1929. (1, 3, 32),
  1930. (1, 4, 31),
  1931. (1, 5, 32),
  1932. (1, 6, 31),
  1933. (1, 7, 32),
  1934. (1, 8, 32),
  1935. (1, 9, 31),
  1936. (1, 10, 32),
  1937. (1, 11, 31),
  1938. (1, 12, 32),
  1939. )
  1940. gooddata = \
  1941. (
  1942. (1, '1970-01-01Z', (1970, 1, 1)),
  1943. (1.5, '1970-01-01Z', (1970, 1, 1)),
  1944. ((2,), '0002-01-01Z', (2, 1, 1)),
  1945. ((2, 3), '0002-03-01Z', (2, 3, 1)),
  1946. ((-2, 3, 4), '-0002-03-04Z', (-2, 3, 4)),
  1947. ((2, 3, 4), '0002-03-04Z', (2, 3, 4)),
  1948. ((10, 2, 3), '0010-02-03Z', (10, 2, 3)),
  1949. ((100, 2, 3), '0100-02-03Z', (100, 2, 3)),
  1950. ((1970, 2, 3), '1970-02-03Z', (1970, 2, 3)),
  1951. ((-1970, 2, 3), '-1970-02-03Z', (-1970, 2, 3)),
  1952. ((1970, 2.0, 3.0), '1970-02-03Z', (1970, 2, 3)),
  1953. ((11990, 1, 2), '11990-01-02Z', (11990, 1, 2)),
  1954. ((1e15, 1, 2), '1000000000000000-01-02Z', (1e15, 1, 2)),
  1955. ((-1e15, 1, 2), '-1000000000000000-01-02Z', (-1e15, 1, 2)),
  1956. ((1000000000000000, 1, 2), '1000000000000000-01-02Z',
  1957. (1e15, 1, 2)),
  1958. ((-1000000000000000, 1, 2), '-1000000000000000-01-02Z',
  1959. (-1e15, 1, 2)),
  1960. )
  1961. parsedata = \
  1962. (
  1963. # Some strings that won't match the r.e.
  1964. ('hello', N),
  1965. ('1970 -01 -01Z', N),
  1966. ('0001-02-03z', N),
  1967. # Invalid ranges
  1968. ('2001-00-03Z', N),
  1969. ('2001-13-03Z', N),
  1970. ('2001-02-00Z', N),
  1971. ('2001-02-29Z', N),
  1972. ('2000-02-30Z', N),
  1973. ('1900-02-29Z', N),
  1974. ('2001-01-32Z', N),
  1975. ('2001-03-32Z', N),
  1976. ('2001-04-31Z', N),
  1977. ('2001-05-32Z', N),
  1978. ('2001-06-31Z', N),
  1979. ('2001-07-32Z', N),
  1980. ('2001-08-32Z', N),
  1981. ('2001-09-31Z', N),
  1982. ('2001-10-32Z', N),
  1983. ('2001-11-31Z', N),
  1984. ('2001-12-32Z', N),
  1985. # Whitespace
  1986. (ws + '1970-01-01Z' + ws, (1970, 1, 1)),
  1987. # No timezones
  1988. ('11971-02-03', (11971, 2, 3)),
  1989. ('1971-02-03', (1971, 2, 3)),
  1990. ('-1971-02-03', (-1971, 2, 3)),
  1991. # Non-zulu
  1992. ('11971-02-03-07:08', (11971, 2, 3)),
  1993. ('11971-02-03+07:08', (11971, 2, 2)),
  1994. ('-11971-02-03-07:08', (-11971, 2, 3)),
  1995. ('-11971-02-03+07:08', (-11971, 2, 2)),
  1996. ('1971-02-03-07:08', (1971, 2, 3)),
  1997. ('1971-02-03+07:08', (1971, 2, 2)),
  1998. ('-1971-02-03-07:08', (-1971, 2, 3)),
  1999. ('-1971-02-03+07:08', (-1971, 2, 2)),
  2000. # Edgepoints (ranges)
  2001. ('2001-01-03Z', (2001, 1, 3)),
  2002. ('2001-12-03Z', (2001, 12, 3)),
  2003. ('2001-02-01Z', (2001, 2, 1)),
  2004. ('2001-02-28Z', (2001, 2, 28)),
  2005. ('2000-02-29Z', (2000, 2, 29)),
  2006. ('1900-02-28Z', (1900, 2, 28)),
  2007. ('2001-01-31Z', (2001, 1, 31)),
  2008. ('2001-03-31Z', (2001, 3, 31)),
  2009. ('2001-04-30Z', (2001, 4, 30)),
  2010. ('2001-05-31Z', (2001, 5, 31)),
  2011. ('2001-06-30Z', (2001, 6, 30)),
  2012. ('2001-07-31Z', (2001, 7, 31)),
  2013. ('2001-08-31Z', (2001, 8, 31)),
  2014. ('2001-09-30Z', (2001, 9, 30)),
  2015. ('2001-10-31Z', (2001, 10, 31)),
  2016. ('2001-11-30Z', (2001, 11, 30)),
  2017. ('2001-12-31Z', (2001, 12, 31)),
  2018. # Edgepoints (crossing boundaries)
  2019. ('0001-01-01+07:08', (0, 12, 31)),
  2020. ('-0004-01-01+07:08', (-5, 12, 31)),
  2021. ('2001-03-01+07:08', (2001, 2, 28)),
  2022. ('2000-03-01+07:08', (2000, 2, 29)),
  2023. ('1900-03-01+07:08', (1900, 2, 28)),
  2024. )
  2025. for t in (dateType,):
  2026. self.allTests(t, baddata, gooddata, parsedata)
  2027. def testGYearMonth(self):
  2028. baddata = \
  2029. (
  2030. 'hello',
  2031. ('hello',),
  2032. (1, 2, 3),
  2033. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  2034. (1, 2, 3.5),
  2035. (1, 'hello'),
  2036. (1, 2.5),
  2037. (1, 0),
  2038. (1, 13),
  2039. )
  2040. gooddata = \
  2041. (
  2042. (1, '1970-01Z', (1970, 1)),
  2043. (1.5, '1970-01Z', (1970, 1)),
  2044. ((2,), '0002-01Z', (2, 1)),
  2045. ((2, 3), '0002-03Z', (2, 3)),
  2046. ((-2, 3), '-0002-03Z', (-2, 3)),
  2047. ((10, 2), '0010-02Z', (10, 2)),
  2048. ((100, 2), '0100-02Z', (100, 2)),
  2049. ((1970, 2), '1970-02Z', (1970, 2)),
  2050. ((-1970, 2), '-1970-02Z', (-1970, 2)),
  2051. ((1970, 2.0), '1970-02Z', (1970, 2)),
  2052. ((11990, 1), '11990-01Z', (11990, 1)),
  2053. ((1e15, 1), '1000000000000000-01Z', (1e15, 1)),
  2054. ((-1e15, 1), '-1000000000000000-01Z', (-1e15, 1)),
  2055. ((1000000000000000, 1), '1000000000000000-01Z', (1e15, 1)),
  2056. ((-1000000000000000, 1), '-1000000000000000-01Z', (-1e15, 1)),
  2057. )
  2058. parsedata = \
  2059. (
  2060. # Some strings that won't match the r.e.
  2061. ('hello', N),
  2062. ('1970 -01Z', N),
  2063. ('0001-02z', N),
  2064. # Invalid ranges
  2065. ('2001-00Z', N),
  2066. ('2001-13Z', N),
  2067. # Whitespace
  2068. (ws + '1970-01Z' + ws, (1970, 1)),
  2069. # No timezones
  2070. ('11971-02', (11971, 2)),
  2071. ('1971-02', (1971, 2)),
  2072. ('-1971-02', (-1971, 2)),
  2073. # Non-zulu
  2074. ('11971-02-07:08', (11971, 2)),
  2075. ('11971-02+07:08', (11971, 1)),
  2076. ('-11971-02-07:08', (-11971, 2)),
  2077. ('-11971-02+07:08', (-11971, 1)),
  2078. ('1971-02-07:08', (1971, 2)),
  2079. ('1971-02+07:08', (1971, 1)),
  2080. ('-1971-02-07:08', (-1971, 2)),
  2081. ('-1971-02+07:08', (-1971, 1)),
  2082. # Edgepoints (ranges)
  2083. ('2001-01Z', (2001, 1)),
  2084. ('2001-12Z', (2001, 12)),
  2085. # Edgepoints (crossing boundaries)
  2086. ('0001-01+07:08', (0, 12)),
  2087. ('-0004-01+07:08', (-5, 12)),
  2088. ('2001-03+07:08', (2001, 2)),
  2089. ('2000-03+07:08', (2000, 2)),
  2090. ('1900-03+07:08', (1900, 2)),
  2091. )
  2092. for t in (gYearMonthType,):
  2093. self.allTests(t, baddata, gooddata, parsedata)
  2094. def testGYearAndYear(self):
  2095. baddata = \
  2096. (
  2097. 'hello',
  2098. ('hello',),
  2099. (1, 2),
  2100. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  2101. (2.5,),
  2102. )
  2103. gooddata = \
  2104. (
  2105. (1, '0001Z', 1),
  2106. (10, '0010Z', 10),
  2107. (100, '0100Z', 100),
  2108. (1970, '1970Z', 1970),
  2109. (-1970, '-1970Z', -1970),
  2110. (1970, '1970Z', 1970),
  2111. (11990.0, '11990Z', 11990),
  2112. (1e15, '1000000000000000Z', 1e15),
  2113. (-1e15, '-1000000000000000Z', -1e15),
  2114. (1000000000000000, '1000000000000000Z', 1e15),
  2115. (-1000000000000000, '-1000000000000000Z', -1e15),
  2116. )
  2117. parsedata = \
  2118. (
  2119. # Some strings that won't match the r.e.
  2120. ('hello', N),
  2121. ('197OZ', N),
  2122. ('0001z', N),
  2123. # Whitespace
  2124. (ws + '1970Z' + ws, 1970),
  2125. # No timezones
  2126. ('11971', 11971),
  2127. ('1971', 1971),
  2128. ('-1971', -1971),
  2129. # Non-zulu
  2130. ('11971-07:08', 11971),
  2131. ('11971+07:08', 11970),
  2132. ('-11971-07:08', -11971),
  2133. ('-11971+07:08', -11972),
  2134. ('1971-07:08', 1971),
  2135. ('1971+07:08', 1970),
  2136. ('-1971-07:08', -1971),
  2137. ('-1971+07:08', -1972),
  2138. # Edgepoints (crossing boundaries)
  2139. ('0001+07:08', 0),
  2140. ('-0004+07:08', -5),
  2141. )
  2142. for t in (gYearType, yearType):
  2143. self.allTests(t, baddata, gooddata, parsedata)
  2144. def testCentury(self):
  2145. baddata = \
  2146. (
  2147. 'hello',
  2148. ('hello',),
  2149. (1, 2),
  2150. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  2151. (2.5,),
  2152. )
  2153. gooddata = \
  2154. (
  2155. (1, '01Z', 1),
  2156. (10, '10Z', 10),
  2157. (100, '100Z', 100),
  2158. (19, '19Z', 19),
  2159. (-19, '-19Z', -19),
  2160. (19, '19Z', 19),
  2161. (119.0, '119Z', 119),
  2162. (1e15, '1000000000000000Z', 1e15),
  2163. (-1e15, '-1000000000000000Z', -1e15),
  2164. (1000000000000000, '1000000000000000Z', 1e15),
  2165. (-1000000000000000, '-1000000000000000Z', -1e15),
  2166. )
  2167. parsedata = \
  2168. (
  2169. # Some strings that won't match the r.e.
  2170. ('hello', N),
  2171. ('197OZ', N),
  2172. ('0001z', N),
  2173. # Whitespace
  2174. (ws + '1970Z' + ws, 1970),
  2175. # No timezones
  2176. ('11971', 11971),
  2177. ('1971', 1971),
  2178. ('-1971', -1971),
  2179. # Non-zulu
  2180. ('11971-07:08', 11971),
  2181. ('11971+07:08', 11970),
  2182. ('-11971-07:08', -11971),
  2183. ('-11971+07:08', -11972),
  2184. ('1971-07:08', 1971),
  2185. ('1971+07:08', 1970),
  2186. ('-1971-07:08', -1971),
  2187. ('-1971+07:08', -1972),
  2188. # Edgepoints (crossing boundaries)
  2189. ('0001+07:08', 0),
  2190. ('-0004+07:08', -5),
  2191. )
  2192. for t in (centuryType,):
  2193. self.allTests(t, baddata, gooddata, parsedata)
  2194. def testGMonthDayAndRecurringDate(self):
  2195. baddata = \
  2196. (
  2197. 'hello',
  2198. ('hello',),
  2199. (3, 4, 5),
  2200. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  2201. (4, 5, 'hello'),
  2202. (2.5, 3),
  2203. (0, 3),
  2204. (13, 3),
  2205. (1, 0),
  2206. (1, 32),
  2207. (2, 29),
  2208. (3, 32),
  2209. (4, 31),
  2210. (5, 32),
  2211. (6, 31),
  2212. (7, 32),
  2213. (8, 32),
  2214. (9, 31),
  2215. (10, 32),
  2216. (11, 31),
  2217. (12, 32),
  2218. )
  2219. gooddata = \
  2220. (
  2221. (1, '--01-01Z', (1, 1)),
  2222. (1.5, '--01-01Z', (1, 1)),
  2223. ((2,), '--02-01Z', (2, 1)),
  2224. ((2, 3), '--02-03Z', (2, 3)),
  2225. ((10, 2), '--10-02Z', (10, 2)),
  2226. )
  2227. parsedata = \
  2228. (
  2229. # Some strings that won't match the r.e.
  2230. ('hello', N),
  2231. ('--01 -01Z', N),
  2232. ('--02-03z', N),
  2233. # Invalid ranges
  2234. ('--00-03Z', N),
  2235. ('--13-03Z', N),
  2236. ('--01-32Z', N),
  2237. ('--02-00Z', N),
  2238. ('--02-29Z', N),
  2239. ('--03-32Z', N),
  2240. ('--04-31Z', N),
  2241. ('--05-32Z', N),
  2242. ('--06-31Z', N),
  2243. ('--07-32Z', N),
  2244. ('--08-32Z', N),
  2245. ('--09-31Z', N),
  2246. ('--10-32Z', N),
  2247. ('--11-31Z', N),
  2248. ('--12-32Z', N),
  2249. # Whitespace
  2250. (ws + '--01-01Z' + ws, (1, 1)),
  2251. # No timezones
  2252. ('--02-03', (2, 3)),
  2253. # Non-zulu
  2254. ('--02-03-07:08', (2, 3)),
  2255. ('--02-03+07:08', (2, 2)),
  2256. # Edgepoints (ranges)
  2257. ('--01-03Z', (1, 3)),
  2258. ('--12-03Z', (12, 3)),
  2259. ('--01-31Z', (1, 31)),
  2260. ('--02-01Z', (2, 1)),
  2261. ('--02-28Z', (2, 28)),
  2262. ('--03-31Z', (3, 31)),
  2263. ('--04-30Z', (4, 30)),
  2264. ('--05-31Z', (5, 31)),
  2265. ('--06-30Z', (6, 30)),
  2266. ('--07-31Z', (7, 31)),
  2267. ('--08-31Z', (8, 31)),
  2268. ('--09-30Z', (9, 30)),
  2269. ('--10-31Z', (10, 31)),
  2270. ('--11-30Z', (11, 30)),
  2271. ('--12-31Z', (12, 31)),
  2272. # Edgepoints (crossing boundaries)
  2273. ('--01-01+07:08', (12, 31)),
  2274. ('--03-01+07:08', (2, 28)),
  2275. )
  2276. for t in (gMonthDayType, recurringDateType):
  2277. self.allTests(t, baddata, gooddata, parsedata)
  2278. def testGMonthAndMonth(self):
  2279. baddata = \
  2280. (
  2281. 'hello',
  2282. ('hello',),
  2283. (3, 4,),
  2284. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  2285. (2.5,),
  2286. (0,),
  2287. (13,),
  2288. )
  2289. gooddata = \
  2290. (
  2291. (1, '--01--Z', 1),
  2292. ((2,), '--02--Z', 2),
  2293. ((10,), '--10--Z', 10),
  2294. )
  2295. parsedata = \
  2296. (
  2297. # Some strings that won't match the r.e.
  2298. ('hello', N),
  2299. ('--01 --Z', N),
  2300. ('--03--z', N),
  2301. # Invalid ranges
  2302. ('--00--Z', N),
  2303. ('--13--Z', N),
  2304. # Whitespace
  2305. (ws + '--01--Z' + ws, 1),
  2306. # No timezones
  2307. ('--03--', 3),
  2308. # Non-zulu
  2309. ('--03---07:08', 3),
  2310. ('--03--+07:08', 2),
  2311. # Edgepoints (ranges)
  2312. ('--01--Z', 1),
  2313. ('--12--Z', 12),
  2314. # Edgepoints (crossing boundaries)
  2315. ('--01--+07:08', 12),
  2316. ('--12---07:08', 12),
  2317. )
  2318. for t in (gMonthType, monthType):
  2319. self.allTests(t, baddata, gooddata, parsedata)
  2320. def testGDayAndRecurringDay(self):
  2321. baddata = \
  2322. (
  2323. 'hello',
  2324. ('hello',),
  2325. (3, 4,),
  2326. (1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
  2327. (2.5,),
  2328. (0,),
  2329. (32,),
  2330. )
  2331. gooddata = \
  2332. (
  2333. (1, '---01Z', 1),
  2334. ((2,), '---02Z', 2),
  2335. ((10,), '---10Z', 10),
  2336. )
  2337. parsedata = \
  2338. (
  2339. # Some strings that won't match the r.e.
  2340. ('hello', N),
  2341. ('---01 Z', N),
  2342. ('---03z', N),
  2343. # Invalid ranges
  2344. ('---00Z', N),
  2345. ('---32Z', N),
  2346. # Whitespace
  2347. (ws + '---01Z' + ws, 1),
  2348. # No timezones
  2349. ('---03', 3),
  2350. # Non-zulu
  2351. ('---03-07:08', 3),
  2352. ('---03+07:08', 2),
  2353. # Edgepoints (ranges)
  2354. ('---01Z', 1),
  2355. ('---31Z', 31),
  2356. # Edgepoints (crossing boundaries)
  2357. ('---01+07:08', 31),
  2358. ('---31-07:08', 31),
  2359. )
  2360. for t in (gDayType, recurringDayType):
  2361. self.allTests(t, baddata, gooddata, parsedata)
  2362. def testInteger(self):
  2363. # First some things that shouldn't be valid
  2364. test = ('hello', 3.14, (), [], {})
  2365. t = integerType
  2366. for i in test:
  2367. try:
  2368. t(i)
  2369. raise AssertionError("instantiated a %s with a bad value (%s)" % \
  2370. (t.__name__, repr(i)))
  2371. except AssertionError:
  2372. raise
  2373. except ValueError:
  2374. pass
  2375. # Now some things that should
  2376. for i in (10, 23, 1111111111111111111111111111111111111111111111111111):
  2377. x = integerType(i)
  2378. d = x._marshalData()
  2379. if d != str(i):
  2380. raise AssertionError("expected %d, got %s" % (i, d))
  2381. y = buildSOAP(x)
  2382. z = parseSOAPRPC(y)
  2383. if z != i:
  2384. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  2385. # Now test parsing, both valid and invalid
  2386. test = (('hello', N), ('3.14', N), ('10 000', N),
  2387. ('1', 1),
  2388. ('123456789012345678901234567890', 123456789012345678901234567890),
  2389. (ws + '12' + ws, 12))
  2390. for i in test:
  2391. try:
  2392. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4],
  2393. i[0]))
  2394. if z != i[1]:
  2395. raise AssertionError("%s: expected %s, got %s" % \
  2396. (i[0], i[1], repr(z)))
  2397. except AssertionError:
  2398. raise
  2399. except:
  2400. if i[1] != N:
  2401. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  2402. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  2403. def testNonPositiveInteger(self):
  2404. # First some things that shouldn't be valid
  2405. test = ('hello', 3.14, (), [], {}, 1, 23)
  2406. for t in (nonPositiveIntegerType, non_Positive_IntegerType):
  2407. for i in test:
  2408. try:
  2409. t(i)
  2410. raise AssertionError("instantiated a t with a bad value (%s)" % \
  2411. (t.__name__, repr(i)))
  2412. except AssertionError:
  2413. raise
  2414. except ValueError:
  2415. pass
  2416. # Now some things that should
  2417. for i in (0, -23, -1111111111111111111111111111111111111111111111111):
  2418. x = t(i)
  2419. d = x._marshalData()
  2420. if d != str(i):
  2421. raise AssertionError("expected %d, got %s" % (i, d))
  2422. y = buildSOAP(x)
  2423. z = parseSOAPRPC(y)
  2424. if z != i:
  2425. raise AssertionError("%s: expected %s, got %s" % \
  2426. (i[0], i[1], repr(z)))
  2427. # Now test parsing, both valid and invalid
  2428. test = (('hello', N), ('3.14', N), ('-10 000', N), ('1', N),
  2429. ('0', 0),
  2430. ('-1', -1),
  2431. ('-123456789012345678901234567890', -123456789012345678901234567890),
  2432. (ws + '-12' + ws, -12))
  2433. for i in test:
  2434. try:
  2435. if t == nonPositiveIntegerType:
  2436. n = t.__name__[:-4]
  2437. else:
  2438. n = 'non-positive-integer'
  2439. z = parseSOAPRPC(self.build_xml(t._validURIs[0], n, i[0]))
  2440. if z != i[1]:
  2441. raise AssertionError("%s: expected %s, got %s" % \
  2442. (i[0], i[1], repr(z)))
  2443. except AssertionError:
  2444. raise
  2445. except:
  2446. if i[1] != N:
  2447. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  2448. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  2449. def testNegativeInteger(self):
  2450. # First some things that shouldn't be valid
  2451. test = ('hello', 3.14, (), [], {}, 0, 23)
  2452. for t in (negativeIntegerType, negative_IntegerType):
  2453. for i in test:
  2454. try:
  2455. t(i)
  2456. raise AssertionError("instantiated a %s with a bad value (%s)" % \
  2457. (t.__name__, repr(i)))
  2458. except AssertionError:
  2459. raise
  2460. except ValueError:
  2461. pass
  2462. # Now some things that should
  2463. for i in (-1, -23, -111111111111111111111111111111111111111111111111):
  2464. x = t(i)
  2465. d = x._marshalData()
  2466. if d != str(i):
  2467. raise AssertionError("expected %d, got %s" % (i, d))
  2468. y = buildSOAP(x)
  2469. z = parseSOAPRPC(y)
  2470. if z != i:
  2471. raise AssertionError("%s: expected %s, got %s" % \
  2472. (i[0], i[1], repr(z)))
  2473. # Now test parsing, both valid and invalid
  2474. test = (('hello', N), ('3.14', N), ('-10 000', N), ('1', N),
  2475. ('0', N),
  2476. ('-1', -1),
  2477. ('-123456789012345678901234567890', -123456789012345678901234567890),
  2478. (ws + '-12' + ws, -12))
  2479. for i in test:
  2480. try:
  2481. if t == negativeIntegerType:
  2482. n = t.__name__[:-4]
  2483. else:
  2484. n = 'negative-integer'
  2485. z = parseSOAPRPC(self.build_xml(t._validURIs[0], n, i[0]))
  2486. if z != i[1]:
  2487. raise AssertionError("expected %s, got %s" % (i[1], repr(z)))
  2488. except AssertionError:
  2489. raise
  2490. except:
  2491. if i[1] != N:
  2492. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  2493. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  2494. def testLong(self):
  2495. # First some things that shouldn't be valid
  2496. test = ('hello', 3.14, (), [], {},
  2497. -9223372036854775809, 9223372036854775808)
  2498. t = longType
  2499. for i in test:
  2500. try:
  2501. t(i)
  2502. raise AssertionError("instantiated a %s with a bad value (%s)" % \
  2503. (t.__name__, repr(i)))
  2504. except AssertionError:
  2505. raise
  2506. except ValueError:
  2507. pass
  2508. # Now some things that should
  2509. for i in (-1, -23, -9223372036854775808, 9223372036854775807):
  2510. x = t(i)
  2511. d = x._marshalData()
  2512. if d != str(i):
  2513. raise AssertionError("expected %d, got %s" % (i, d))
  2514. y = buildSOAP(x)
  2515. z = parseSOAPRPC(y)
  2516. if z != i:
  2517. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  2518. # Now test parsing, both valid and invalid
  2519. test = (('hello', N), ('3.14', N), ('-10 000', N),
  2520. ('-9223372036854775809', N), ('9223372036854775808', N),
  2521. ('-1', -1), ('0', 0), ('1', 1),
  2522. ('-9223372036854775808', -9223372036854775808),
  2523. ('9223372036854775807', 9223372036854775807),
  2524. (ws + '-12' + ws, -12))
  2525. for i in test:
  2526. try:
  2527. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  2528. if z != i[1]:
  2529. raise AssertionError("%s: expected %s, got %s" % \
  2530. (i[0], i[1], repr(z)))
  2531. except AssertionError:
  2532. raise
  2533. except:
  2534. if i[1] != N:
  2535. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  2536. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  2537. def testInt(self):
  2538. # First some things that shouldn't be valid
  2539. test = ('hello', 3.14, (), [], {}, -2147483649, 2147483648)
  2540. t = intType
  2541. for i in test:
  2542. try:
  2543. t(i)
  2544. raise AssertionError("instantiated a %s with a bad value (%s)" % \
  2545. (t.__name__, repr(i)))
  2546. except AssertionError:
  2547. raise
  2548. except ValueError:
  2549. pass
  2550. # Now some things that should
  2551. for i in (-1, -23, -2147483648, 2147483647):
  2552. x = intType(i)
  2553. d = x._marshalData()
  2554. if d != str(i):
  2555. raise AssertionError("expected %d, got %s" % (i, d))
  2556. y = buildSOAP(x)
  2557. z = parseSOAPRPC(y)
  2558. if z != i:
  2559. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  2560. # Now test parsing, both valid and invalid
  2561. test = (('hello', N), ('3.14', N), ('-10 000', N),
  2562. ('-2147483649', N), ('2147483648', N),
  2563. ('-1', -1), ('0', 0), ('1', 1),
  2564. ('-2147483648', -2147483648),
  2565. ('2147483647', 2147483647),
  2566. (ws + '-12' + ws, -12))
  2567. for i in test:
  2568. try:
  2569. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  2570. if z != i[1]:
  2571. raise AssertionError("%s: expected %s, got %s" % \
  2572. (i[0], i[1], repr(z)))
  2573. except AssertionError:
  2574. raise
  2575. except:
  2576. if i[1] != N:
  2577. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  2578. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  2579. def testShort(self):
  2580. # First some things that shouldn't be valid
  2581. test = ('hello', 3.14, (), [], {}, -32769, 32768)
  2582. t = shortType
  2583. for i in test:
  2584. try:
  2585. t(i)
  2586. raise AssertionError("instantiated a %s with a bad value (%s)" % \
  2587. (t.__name__, repr(i)))
  2588. except AssertionError:
  2589. raise
  2590. except ValueError:
  2591. pass
  2592. # Now some things that should
  2593. for i in (-1, -23, -32768, 32767):
  2594. x = t(i)
  2595. d = x._marshalData()
  2596. if d != str(i):
  2597. raise AssertionError("expected %d, got %s" % (i, d))
  2598. y = buildSOAP(x)
  2599. z = parseSOAPRPC(y)
  2600. if z != i:
  2601. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  2602. # Now test parsing, both valid and invalid
  2603. test = (('hello', N), ('3.14', N), ('-10 000', N),
  2604. ('-32769', N), ('32768', N),
  2605. ('-1', -1), ('0', 0), ('1', 1),
  2606. ('-32768', -32768),
  2607. ('32767', 32767),
  2608. (ws + '-12' + ws, -12))
  2609. for i in test:
  2610. try:
  2611. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  2612. if z != i[1]:
  2613. raise AssertionError("%s: expected %s, got %s" % \
  2614. (i[0], i[1], repr(z)))
  2615. except AssertionError:
  2616. raise
  2617. except:
  2618. if i[1] != N:
  2619. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  2620. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  2621. def testByte(self):
  2622. # First some things that shouldn't be valid
  2623. test = ('hello', 3.14, (), [], {}, -129, 128)
  2624. t = byteType
  2625. for i in test:
  2626. try:
  2627. t(i)
  2628. raise AssertionError("instantiated a %s with a bad value (%s)" % \
  2629. (t.__name__, repr(i)))
  2630. except AssertionError:
  2631. raise
  2632. except ValueError:
  2633. pass
  2634. # Now some things that should
  2635. for i in (-1, -23, -128, 127):
  2636. x = t(i)
  2637. d = x._marshalData()
  2638. if d != str(i):
  2639. raise AssertionError("expected %d, got %s" % (i, d))
  2640. y = buildSOAP(x)
  2641. z = parseSOAPRPC(y)
  2642. if z != i:
  2643. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  2644. # Now test parsing, both valid and invalid
  2645. test = (('hello', N), ('3.14', N), ('-10 000', N),
  2646. ('-129', N), ('128', N),
  2647. ('-1', -1), ('0', 0), ('1', 1),
  2648. ('-128', -128),
  2649. ('127', 127),
  2650. (ws + '-12' + ws, -12))
  2651. for i in test:
  2652. try:
  2653. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  2654. if z != i[1]:
  2655. raise AssertionError("%s: expected %s, got %s" % \
  2656. (i[0], i[1], repr(z)))
  2657. except AssertionError:
  2658. raise
  2659. except:
  2660. if i[1] != N:
  2661. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  2662. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  2663. def testNonNegativeInteger(self):
  2664. # First some things that shouldn't be valid
  2665. test = ('hello', 3.14, (), [], {}, -42, -1)
  2666. for t in (nonNegativeIntegerType, non_Negative_IntegerType):
  2667. for i in test:
  2668. try:
  2669. t(i)
  2670. raise AssertionError("instantiated a %s with a bad value (%s)" % \
  2671. (t.__name__, repr(i)))
  2672. except AssertionError:
  2673. raise
  2674. except ValueError:
  2675. pass
  2676. # Now some things that should
  2677. for i in (0, 1, 23, 111111111111111111111111111111111111111111111111):
  2678. x = t(i)
  2679. d = x._marshalData()
  2680. if d != str(i):
  2681. raise AssertionError("expected %d, got %s" % (i, d))
  2682. y = buildSOAP(x)
  2683. z = parseSOAPRPC(y)
  2684. if z != i:
  2685. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  2686. # Now test parsing, both valid and invalid
  2687. test = (('hello', N), ('3.14', N), ('-10 000', N), ('-1', N),
  2688. ('0', 0),
  2689. ('1', 1),
  2690. ('123456789012345678901234567890', 123456789012345678901234567890),
  2691. (ws + '12' + ws, 12))
  2692. for i in test:
  2693. try:
  2694. if t == nonNegativeIntegerType:
  2695. n = t.__name__[:-4]
  2696. else:
  2697. n = 'non-negative-integer'
  2698. z = parseSOAPRPC(self.build_xml(t._validURIs[0], n, i[0]))
  2699. if z != i[1]:
  2700. raise AssertionError("%s: expected %s, got %s" % \
  2701. (i[0], i[1], repr(z)))
  2702. except AssertionError:
  2703. raise
  2704. except:
  2705. if i[1] != N:
  2706. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  2707. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  2708. def testUnsignedLong(self):
  2709. # First some things that shouldn't be valid
  2710. test = ('hello', 3.14, (), [], {}, -42, -1, 18446744073709551616)
  2711. t = unsignedLongType
  2712. for i in test:
  2713. try:
  2714. t(i)
  2715. raise AssertionError("instantiated a %s with a bad value (%s)" % \
  2716. (t.__name__, repr(i)))
  2717. except AssertionError:
  2718. raise
  2719. except ValueError:
  2720. pass
  2721. # Now some things that should
  2722. for i in (0, 23, 18446744073709551615):
  2723. x = t(i)
  2724. d = x._marshalData()
  2725. if d != str(i):
  2726. raise AssertionError("expected %d, got %s" % (i, d))
  2727. y = buildSOAP(x)
  2728. z = parseSOAPRPC(y)
  2729. if z != i:
  2730. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  2731. # Now test parsing, both valid and invalid
  2732. test = (('hello', N), ('3.14', N), ('-10 000', N), ('-1', N),
  2733. ('18446744073709551616', N),
  2734. ('0', 0), ('1', 1),
  2735. ('18446744073709551615', 18446744073709551615),
  2736. (ws + '12' + ws, 12))
  2737. for i in test:
  2738. try:
  2739. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  2740. if z != i[1]:
  2741. raise AssertionError("%s: expected %s, got %s" % \
  2742. (i[0], i[1], repr(z)))
  2743. except AssertionError:
  2744. raise
  2745. except:
  2746. if i[1] != N:
  2747. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  2748. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  2749. def testUnsignedInt(self):
  2750. # First some things that shouldn't be valid
  2751. test = ('hello', 3.14, (), [], {}, -42, -1, 4294967296)
  2752. t = unsignedIntType
  2753. for i in test:
  2754. try:
  2755. t(i)
  2756. raise AssertionError("instantiated a %s with a bad value (%s)" % \
  2757. (t.__name__, repr(i)))
  2758. except AssertionError:
  2759. raise
  2760. except ValueError:
  2761. pass
  2762. # Now some things that should
  2763. for i in (0, 23, 4294967295):
  2764. x = t(i)
  2765. d = x._marshalData()
  2766. if d != str(i):
  2767. raise AssertionError("expected %d, got %s" % (i, d))
  2768. y = buildSOAP(x)
  2769. z = parseSOAPRPC(y)
  2770. if z != i:
  2771. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  2772. # Now test parsing, both valid and invalid
  2773. test = (('hello', N), ('3.14', N), ('-10 000', N), ('-1', N),
  2774. ('4294967296', N),
  2775. ('0', 0), ('1', 1),
  2776. ('4294967295', 4294967295),
  2777. (ws + '12' + ws, 12))
  2778. for i in test:
  2779. try:
  2780. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  2781. if z != i[1]:
  2782. raise AssertionError("%s: expected %s, got %s" % \
  2783. (i[0], i[1], repr(z)))
  2784. except AssertionError:
  2785. raise
  2786. except:
  2787. if i[1] != N:
  2788. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  2789. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  2790. def testUnsignedShort(self):
  2791. # First some things that shouldn't be valid
  2792. test = ('hello', 3.14, (), [], {}, -42, -1, 65536)
  2793. t = unsignedShortType
  2794. for i in test:
  2795. try:
  2796. t(i)
  2797. raise AssertionError("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, 23, 65535):
  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. ('65536', N),
  2816. ('0', 0), ('1', 1),
  2817. ('65535', 65535),
  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("parsing %s as %s threw exception %s:%s" % \
  2830. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  2831. def testUnsignedByte(self):
  2832. # First some things that shouldn't be valid
  2833. test = ('hello', 3.14, (), [], {}, -42, -1, 256)
  2834. t = unsignedByteType
  2835. for i in test:
  2836. try:
  2837. t(i)
  2838. raise AssertionError("instantiated a %s with a bad value (%s)" % \
  2839. (t.__name__, repr(i)))
  2840. except AssertionError:
  2841. raise
  2842. except ValueError:
  2843. pass
  2844. # Now some things that should
  2845. for i in (0, 23, 255):
  2846. x = t(i)
  2847. d = x._marshalData()
  2848. if d != str(i):
  2849. raise AssertionError("expected %d, got %s" % (i, d))
  2850. y = buildSOAP(x)
  2851. z = parseSOAPRPC(y)
  2852. if z != i:
  2853. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  2854. # Now test parsing, both valid and invalid
  2855. test = (('hello', N), ('3.14', N), ('-10 000', N), ('-1', N),
  2856. ('256', N),
  2857. ('0', 0), ('1', 1),
  2858. ('255', 255),
  2859. (ws + '12' + ws, 12))
  2860. for i in test:
  2861. try:
  2862. z = parseSOAPRPC(self.build_xml(t._validURIs[0], t.__name__[:-4], i[0]))
  2863. if z != i[1]:
  2864. raise AssertionError("%s: expected %s, got %s" % \
  2865. (i[0], i[1], repr(z)))
  2866. except AssertionError:
  2867. raise
  2868. except:
  2869. if i[1] != N:
  2870. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  2871. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  2872. def testPositiveInteger(self):
  2873. # First some things that shouldn't be valid
  2874. test = ('hello', 3.14, (), [], {}, -42, -1, 0)
  2875. for t in (positiveIntegerType, positive_IntegerType):
  2876. for i in test:
  2877. try:
  2878. t(i)
  2879. raise AssertionError("instantiated a t with a bad value (%s)" % \
  2880. (t.__name__, repr(i)))
  2881. except AssertionError:
  2882. raise
  2883. except ValueError:
  2884. pass
  2885. # Now some things that should
  2886. for i in (1, 23, 1111111111111111111111111111111111111111111111111111):
  2887. x = t(i)
  2888. d = x._marshalData()
  2889. if d != str(i):
  2890. raise AssertionError("expected %d, got %s" % (i, d))
  2891. y = buildSOAP(x)
  2892. z = parseSOAPRPC(y)
  2893. if z != i:
  2894. raise AssertionError("expected %s, got %s" % (repr(i), repr(z)))
  2895. # Now test parsing, both valid and invalid
  2896. test = (('hello', N), ('3.14', N), ('-10 000', N), ('-1', N),
  2897. ('0', N), ('1', 1),
  2898. ('123456789012345678901234567890', 123456789012345678901234567890),
  2899. (ws + '12' + ws, 12))
  2900. for i in test:
  2901. try:
  2902. if t == positiveIntegerType:
  2903. n = t.__name__[:-4]
  2904. else:
  2905. n = 'positive-integer'
  2906. z = parseSOAPRPC(self.build_xml(t._validURIs[0], n, i[0]))
  2907. if z != i[1]:
  2908. raise AssertionError("%s: expected %s, got %s" % \
  2909. (i[0], i[1], repr(z)))
  2910. except AssertionError:
  2911. raise
  2912. except:
  2913. if i[1] != N:
  2914. raise AssertionError("parsing %s as %s threw exception %s:%s" % \
  2915. (i[0], t.__name__, sys.exc_info()[0], sys.exc_info()[1]))
  2916. def testUntyped(self):
  2917. # Make sure untypedType really isn't typed
  2918. a = stringType('hello', name = 'a')
  2919. b = untypedType('earth', name = 'b')
  2920. x = buildSOAP((a, b))
  2921. #print "x=",x
  2922. self.assertTrue(x.find('<a xsi:type="xsd:string" SOAP-ENC:root="1">hello</a>') != -1)
  2923. self.assertTrue(x.find('<b SOAP-ENC:root="1">earth</b>') != -1)
  2924. # Now some Array tests
  2925. def testArray(self):
  2926. env = '''<?xml version="1.0" encoding="UTF-8"?>
  2927. <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/">
  2928. %s
  2929. </SOAP-ENV:Envelope>'''
  2930. xml = env % '''<SOAP-ENV:Body>
  2931. <_1 SOAP-ENC:arrayType="xsd:int[4]" SOAP-ENC:offset="[2]" xsi:type="SOAP-ENC:Array">
  2932. <_2 SOAP-ENC:arrayType="xsd:int[2]" xsi:type="SOAP-ENC:Array">
  2933. <item>1</item>
  2934. <item>2</item>
  2935. </_2>
  2936. <_3 SOAP-ENC:arrayType="xsd:int[2]" xsi:type="SOAP-ENC:Array">
  2937. <item>3</item>
  2938. <item>4</item>
  2939. </_3>
  2940. </_1>
  2941. </SOAP-ENV:Body>'''
  2942. x = parseSOAPRPC(xml)
  2943. self.assertEqual( x , [None, None, [1, 2], [3, 4]])
  2944. xml = env % '''<SOAP-ENV:Body>
  2945. <_1 SOAP-ENC:arrayType="xsd:int[3,4,2]" SOAP-ENC:offset="[17]" xsi:type="SOAP-ENC:Array">
  2946. <item>1</item>
  2947. <item>2</item>
  2948. <item>3</item>
  2949. <item>4</item>
  2950. <item>5</item>
  2951. <item>6</item>
  2952. <item>7</item>
  2953. </_1>
  2954. </SOAP-ENV:Body>'''
  2955. x = parseSOAPRPC(xml)
  2956. self.assertEqual( x , [
  2957. [[None, None], [None, None], [None, None], [None, None]],
  2958. [[None, None], [None, None], [None, None], [None, None]],
  2959. [[None, 1], [2, 3], [4, 5], [6, 7]]
  2960. ])
  2961. xml = env % '''<SOAP-ENV:Body>
  2962. <_1 SOAP-ENC:arrayType="xsd:int[3,4,2]" xsi:type="SOAP-ENC:Array">
  2963. <item SOAP-ENC:position="[17]">-17</item>
  2964. <item SOAP-ENC:position="[13]">13</item>
  2965. <item SOAP-ENC:position="[22]">-22</item>
  2966. <item SOAP-ENC:position="[1]">1</item>
  2967. <item SOAP-ENC:position="[17]">17</item>
  2968. <item SOAP-ENC:position="[23]">23</item>
  2969. <item SOAP-ENC:position="[6]">6</item>
  2970. </_1>
  2971. </SOAP-ENV:Body>'''
  2972. x = parseSOAPRPC(xml)
  2973. self.assertEqual( x , [
  2974. [[None, 1], [None, None], [None, None], [6, None]],
  2975. [[None, None], [None, None], [None, 13], [None, None]],
  2976. [[None, 17], [None, None], [None, None], [-22, 23]]
  2977. ])
  2978. xml = env % '''<SOAP-ENV:Body>
  2979. <_1 SOAP-ENC:arrayType="xsd:int[4]" SOAP-ENC:offset="[3]" xsi:type="SOAP-ENC:Array">
  2980. <item SOAP-ENC:position="[2]">2</item>
  2981. <item SOAP-ENC:position="[0]">0</item>
  2982. <item SOAP-ENC:position="[1]">1</item>
  2983. <item SOAP-ENC:position="[3]">3</item>
  2984. </_1>
  2985. </SOAP-ENV:Body>'''
  2986. x = parseSOAPRPC(xml)
  2987. self.assertEqual( x , [0, 1, 2, 3])
  2988. xml = env % '''<SOAP-ENV:Body>
  2989. <_1 SOAP-ENC:arrayType="xsd:int[2,3,4]" SOAP-ENC:offset="[23]" xsi:type="SOAP-ENC:Array">
  2990. </_1>
  2991. </SOAP-ENV:Body>'''
  2992. x = parseSOAPRPC(xml)
  2993. self.assertEqual( x , [
  2994. [
  2995. [None, None, None, None],
  2996. [None, None, None, None],
  2997. [None, None, None, None],
  2998. ],
  2999. [
  3000. [None, None, None, None],
  3001. [None, None, None, None],
  3002. [None, None, None, None],
  3003. ]
  3004. ])
  3005. xml = env % '''<SOAP-ENV:Body>
  3006. <_1 SOAP-ENC:arrayType="xsd:int[4]" SOAP-ENC:offset="[3]" xsi:type="SOAP-ENC:Array">
  3007. <item>2</item>
  3008. <item>3</item>
  3009. </_1>
  3010. </SOAP-ENV:Body>'''
  3011. try:
  3012. x = parseSOAPRPC(xml)
  3013. raise AssertionError("full array parsed")
  3014. except AssertionError:
  3015. raise
  3016. except:
  3017. pass
  3018. xml = env % '''<SOAP-ENV:Body>
  3019. <_1 SOAP-ENC:arrayType="xsd:int[2,0,4]" xsi:type="SOAP-ENC:Array">
  3020. </_1>
  3021. </SOAP-ENV:Body>'''
  3022. try:
  3023. x = parseSOAPRPC(xml)
  3024. raise AssertionError("array with bad dimension (0) parsed")
  3025. except AssertionError:
  3026. raise
  3027. except:
  3028. pass
  3029. xml = env % '''<SOAP-ENV:Body>
  3030. <_1 SOAP-ENC:arrayType="xsd:int[2,3,-4]" xsi:type="SOAP-ENC:Array">
  3031. </_1>
  3032. </SOAP-ENV:Body>'''
  3033. try:
  3034. x = parseSOAPRPC(xml)
  3035. raise AssertionError("array with bad dimension (negative) parsed")
  3036. except AssertionError:
  3037. raise
  3038. except:
  3039. pass
  3040. xml = env % '''<SOAP-ENV:Body>
  3041. <_1 SOAP-ENC:arrayType="xsd:int[2,3,4.4]" xsi:type="SOAP-ENC:Array">
  3042. </_1>
  3043. </SOAP-ENV:Body>'''
  3044. try:
  3045. x = parseSOAPRPC(xml)
  3046. raise AssertionError("array with bad dimension (non-integral) parsed")
  3047. except AssertionError:
  3048. raise
  3049. except:
  3050. pass
  3051. xml = env % '''<SOAP-ENV:Body>
  3052. <_1 SOAP-ENC:arrayType="xsd:int[2,hello,4]" xsi:type="SOAP-ENC:Array">
  3053. </_1>
  3054. </SOAP-ENV:Body>'''
  3055. try:
  3056. x = parseSOAPRPC(xml)
  3057. raise AssertionError("array with bad dimension (non-numeric) parsed")
  3058. except AssertionError:
  3059. raise
  3060. except:
  3061. pass
  3062. xml = env % '''<SOAP-ENV:Body>
  3063. <_1 SOAP-ENC:arrayType="xsd:int[2,3,4]" SOAP-ENC:offset="[-4]" xsi:type="SOAP-ENC:Array">
  3064. </_1>
  3065. </SOAP-ENV:Body>'''
  3066. try:
  3067. x = parseSOAPRPC(xml)
  3068. raise AssertionError("array with too large offset parsed")
  3069. except AssertionError:
  3070. raise
  3071. except:
  3072. pass
  3073. xml = env % '''<SOAP-ENV:Body>
  3074. <_1 SOAP-ENC:arrayType="xsd:int[2,3,4]" SOAP-ENC:offset="[24]" xsi:type="SOAP-ENC:Array">
  3075. </_1>
  3076. </SOAP-ENV:Body>'''
  3077. try:
  3078. x = parseSOAPRPC(xml)
  3079. raise AssertionError("array with too large offset parsed")
  3080. except AssertionError:
  3081. raise
  3082. except:
  3083. pass
  3084. xml = env % '''<SOAP-ENV:Body>
  3085. <_1 SOAP-ENC:arrayType="xsd:int[2,3,4]" xsi:type="SOAP-ENC:Array">
  3086. <item SOAP-ENC:position="0">2</item>
  3087. <item>3</item>
  3088. </_1>
  3089. </SOAP-ENV:Body>'''
  3090. try:
  3091. x = parseSOAPRPC(xml)
  3092. raise AssertionError("full array parsed")
  3093. except AssertionError:
  3094. raise
  3095. except:
  3096. pass
  3097. xml = env % '''<SOAP-ENV:Body>
  3098. <myFavoriteNumbers type="SOAP-ENC:Array" SOAP-ENC:arrayType="xsd:int[2]">
  3099. <number>3</number>
  3100. <number>4</number>
  3101. </myFavoriteNumbers>
  3102. </SOAP-ENV:Body>'''
  3103. x = parseSOAPRPC(xml)
  3104. self.assertEqual( x , [3, 4])
  3105. xml = env % '''<SOAP-ENV:Body>
  3106. <SOAP-ENC:Array SOAP-ENC:arrayType="xsd:ur-type[4]">
  3107. <thing xsi:type="xsd:int">12345</thing>
  3108. <thing xsi:type="xsd:decimal">6.789</thing>
  3109. <thing xsi:type="xsd:string">Of Mans First Disobedience, and the Fruit
  3110. Of that Forbidden Tree, whose mortal tast
  3111. Brought Death into the World, and all our woe,</thing>
  3112. <thing xsi:type="xsd2:uriReference">
  3113. http://www.dartmouth.edu/~milton/reading_room/
  3114. </thing>
  3115. </SOAP-ENC:Array>
  3116. </SOAP-ENV:Body>'''
  3117. x = parseSOAPRPC(xml)
  3118. self.assertEqual( x , [12345, 6.789, '''Of Mans First Disobedience, and the Fruit
  3119. Of that Forbidden Tree, whose mortal tast
  3120. Brought Death into the World, and all our woe,''',
  3121. 'http://www.dartmouth.edu/~milton/reading_room/'])
  3122. xml = env % '''<SOAP-ENV:Body>
  3123. <SOAP-ENC:Array SOAP-ENC:arrayType="xyz:Order[2]">
  3124. <Order>
  3125. <Product>Apple</Product>
  3126. <Price>1.56</Price>
  3127. </Order>
  3128. <Order>
  3129. <Product>Peach</Product>
  3130. <Price>1.48</Price>
  3131. </Order>
  3132. </SOAP-ENC:Array>
  3133. </SOAP-ENV:Body>'''
  3134. #x = parseSOAPRPC(xml)
  3135. #print "x=",x
  3136. xml = env % '''<SOAP-ENV:Body>
  3137. <SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[3]">
  3138. <item href="#array-1"/>
  3139. <item href="#array-2"/>
  3140. <item href="#array-2"/>
  3141. </SOAP-ENC:Array>
  3142. <SOAP-ENC:Array id="array-1" SOAP-ENC:arrayType="xsd:string[3]">
  3143. <item>r1c1</item>
  3144. <item>r1c2</item>
  3145. <item>r1c3</item>
  3146. </SOAP-ENC:Array>
  3147. <SOAP-ENC:Array id="array-2" SOAP-ENC:arrayType="xsd:string[2]">
  3148. <item>r2c1</item>
  3149. <item>r2c2</item>
  3150. </SOAP-ENC:Array>
  3151. </SOAP-ENV:Body>'''
  3152. x = parseSOAPRPC(xml)
  3153. self.assertEqual( x , [['r1c1', 'r1c2', 'r1c3'],
  3154. ['r2c1', 'r2c2'], ['r2c1', 'r2c2']])
  3155. xml = env % '''<SOAP-ENV:Body>
  3156. <SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[2,3]">
  3157. <item>r1c1</item>
  3158. <item>r1c2</item>
  3159. <item>r1c3</item>
  3160. <item>r2c1</item>
  3161. <item>r2c2</item>
  3162. <item>r2c3</item>
  3163. </SOAP-ENC:Array>
  3164. </SOAP-ENV:Body>'''
  3165. x = parseSOAPRPC(xml)
  3166. self.assertEqual( x , [['r1c1', 'r1c2', 'r1c3'], ['r2c1', 'r2c2', 'r2c3']])
  3167. xml = env % '''<SOAP-ENV:Body>
  3168. <SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[5]" SOAP-ENC:offset="[2]">
  3169. <item>The third element</item>
  3170. <item>The fourth element</item>
  3171. </SOAP-ENC:Array>
  3172. </SOAP-ENV:Body>'''
  3173. x = parseSOAPRPC(xml)
  3174. self.assertEqual( x , [None, None, 'The third element', 'The fourth element', None])
  3175. xml = env % '''<SOAP-ENV:Body>
  3176. <SOAP-ENC:Array SOAP-ENC:arrayType="xsd:string[,][4]">
  3177. <SOAP-ENC:Array href="#array-1" SOAP-ENC:position="[2]"/>
  3178. </SOAP-ENC:Array>
  3179. <SOAP-ENC:Array id="array-1" SOAP-ENC:arrayType="xsd:string[10,10]">
  3180. <item SOAP-ENC:position="[2,2]">Third row, third col</item>
  3181. <item SOAP-ENC:position="[7,2]">Eighth row, third col</item>
  3182. </SOAP-ENC:Array>
  3183. </SOAP-ENV:Body>'''
  3184. x = parseSOAPRPC(xml)
  3185. # Example using key data
  3186. def testKeyData(self):
  3187. xml = '''<?xml version="1.0" encoding="UTF-8"?>
  3188. <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">
  3189. <soap:Body>
  3190. <xkms:RegisterResult xmlns:xkms="http://www.xkms.org/schema/xkms-2001-01-20">
  3191. <xkms:Result>Success</xkms:Result>
  3192. <xkms:Answer soapenc:arrayType="KeyBinding[1]">
  3193. <xkms:KeyBinding>
  3194. <xkms:Status>Valid</xkms:Status>
  3195. <xkms:KeyID>mailto:actzerotestkeyname</xkms:KeyID>
  3196. <dsig:KeyInfo>
  3197. <dsig:X509Data>
  3198. <dsig:X509Certificate>MIIDPjCCAqegAwIBAgIEOroMvDANBgkqhkiG9w0BAQUFADAxMQswCQYDVQQGEwJVI3nlMkH84ZdPKIyz60sNcVEwJ8kF+B6ZVNimCF+r7BWgLi/Dolce5CpbfMMyexZ+UQEMADrc7331eYS891KXSDQx</dsig:X509Certificate>
  3199. </dsig:X509Data>
  3200. <dsig:KeyName>mailto:actzerotestkeyname</dsig:KeyName>
  3201. <dsig:KeyValue>
  3202. <dsig:RSAKeyValue>
  3203. <dsig:Modulus>wgmV2FY6MBKvtaMmCvCoNi/0hycZkiPKC2PXjRLJKFJ5wjNfF+vWsQQUXxOKUQnu
  3204. HjJqRkx90jJvnEzW3j9FlZFQcZTfJbE0v6BXhhSre2kZvkgcOERmDMeMs//oEA4u
  3205. epnedUwrkPzedWU9AL7c/oN7rk65UuPWf7V8c/4E9bc=</dsig:Modulus>
  3206. <dsig:Exponent>AQAB</dsig:Exponent>
  3207. </dsig:RSAKeyValue>
  3208. </dsig:KeyValue>
  3209. </dsig:KeyInfo>
  3210. </xkms:KeyBinding>
  3211. </xkms:Answer>
  3212. <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>
  3213. </xkms:RegisterResult>
  3214. </soap:Body>
  3215. </soap:Envelope>'''
  3216. x = parseSOAPRPC(xml)
  3217. def testZeroLengthTypedArray(self):
  3218. """
  3219. Test that zero length typed arrays maintain thier type information when
  3220. converted to a SOAP message.
  3221. """
  3222. empty_int = typedArrayType(typed="int")
  3223. empty_int_message = buildSOAP( empty_int )
  3224. self.assertNotEqual( re.search("xsd:int\[0\]", empty_int_message),
  3225. None )
  3226. if __name__ == '__main__':
  3227. print("""
  3228. NOTE: The 'testArray' test will fail because 'referenced' elements are
  3229. included in the return object. This is a known shortcoming of
  3230. the current version of SOAPpy-py3.
  3231. All other tests should succeed.
  3232. """)
  3233. unittest.main()