test_wolframalpha_api.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. # -*- coding: utf-8 -*-
  2. from collections import defaultdict
  3. import mock
  4. from searx.engines import wolframalpha_api
  5. from searx.testing import SearxTestCase
  6. class TestWolframAlphaAPIEngine(SearxTestCase):
  7. def test_request(self):
  8. query = 'test_query'
  9. api_key = 'XXXXXX-XXXXXXXXXX'
  10. dicto = defaultdict(dict)
  11. dicto['api_key'] = api_key
  12. params = wolframalpha_api.request(query, dicto)
  13. self.assertIn('url', params)
  14. self.assertIn(query, params['url'])
  15. self.assertIn('wolframalpha.com', params['url'])
  16. self.assertIn('api_key', params)
  17. self.assertIn(api_key, params['api_key'])
  18. def test_response(self):
  19. self.assertRaises(AttributeError, wolframalpha_api.response, None)
  20. self.assertRaises(AttributeError, wolframalpha_api.response, [])
  21. self.assertRaises(AttributeError, wolframalpha_api.response, '')
  22. self.assertRaises(AttributeError, wolframalpha_api.response, '[]')
  23. xml = '''<?xml version='1.0' encoding='UTF-8'?>
  24. <queryresult success='false' error='false' />
  25. '''
  26. # test failure
  27. response = mock.Mock(content=xml)
  28. self.assertEqual(wolframalpha_api.response(response), [])
  29. xml = """<?xml version='1.0' encoding='UTF-8'?>
  30. <queryresult success='true'
  31. error='false'
  32. numpods='6'
  33. datatypes=''
  34. timedout=''
  35. timedoutpods=''
  36. timing='0.684'
  37. parsetiming='0.138'
  38. parsetimedout='false'
  39. recalculate=''
  40. id='MSPa416020a7966dachc463600000f9c66cc21444cfg'
  41. host='http://www3.wolframalpha.com'
  42. server='6'
  43. related='http://www3.wolframalpha.com/api/v2/relatedQueries.jsp?...'
  44. version='2.6'>
  45. <pod title='Input'
  46. scanner='Identity'
  47. id='Input'
  48. position='100'
  49. error='false'
  50. numsubpods='1'>
  51. <subpod title=''>
  52. <plaintext>sqrt(-1)</plaintext>
  53. </subpod>
  54. </pod>
  55. <pod title='Result'
  56. scanner='Simplification'
  57. id='Result'
  58. position='200'
  59. error='false'
  60. numsubpods='1'
  61. primary='true'>
  62. <subpod title=''>
  63. <plaintext></plaintext>
  64. </subpod>
  65. <states count='1'>
  66. <state name='Step-by-step solution'
  67. input='Result__Step-by-step solution' />
  68. </states>
  69. </pod>
  70. <pod title='Polar coordinates'
  71. scanner='Numeric'
  72. id='PolarCoordinates'
  73. position='300'
  74. error='false'
  75. numsubpods='1'>
  76. <subpod title=''>
  77. <plaintext>r1 (radius), θ90° (angle)</plaintext>
  78. </subpod>
  79. </pod>
  80. <pod title='Position in the complex plane'
  81. scanner='Numeric'
  82. id='PositionInTheComplexPlane'
  83. position='400'
  84. error='false'
  85. numsubpods='1'>
  86. <subpod title=''>
  87. <plaintext></plaintext>
  88. </subpod>
  89. </pod>
  90. <pod title='All 2nd roots of -1'
  91. scanner='RootsOfUnity'
  92. id=''
  93. position='500'
  94. error='false'
  95. numsubpods='2'>
  96. <subpod title=''>
  97. <plaintext> (principal root)</plaintext>
  98. </subpod>
  99. <subpod title=''>
  100. <plaintext>-</plaintext>
  101. </subpod>
  102. </pod>
  103. <pod title='Plot of all roots in the complex plane'
  104. scanner='RootsOfUnity'
  105. id='PlotOfAllRootsInTheComplexPlane'
  106. position='600'
  107. error='false'
  108. numsubpods='1'>
  109. <subpod title=''>
  110. <plaintext></plaintext>
  111. </subpod>
  112. </pod>
  113. </queryresult>
  114. """
  115. # test private user area char in response
  116. response = mock.Mock(content=xml)
  117. results = wolframalpha_api.response(response)
  118. self.assertEqual(type(results), list)
  119. self.assertEqual(len(results), 1)
  120. self.assertIn('i', results[0]['answer'])
  121. xml = """<?xml version='1.0' encoding='UTF-8'?>
  122. <queryresult success='true'
  123. error='false'
  124. numpods='2'
  125. datatypes=''
  126. timedout=''
  127. timedoutpods=''
  128. timing='1.286'
  129. parsetiming='0.255'
  130. parsetimedout='false'
  131. recalculate=''
  132. id='MSPa195222ad740ede5214h30000480ca61h003d3gd6'
  133. host='http://www3.wolframalpha.com'
  134. server='20'
  135. related='http://www3.wolframalpha.com/api/v2/relatedQueries.jsp?id=...'
  136. version='2.6'>
  137. <pod title='Indefinite integral'
  138. scanner='Integral'
  139. id='IndefiniteIntegral'
  140. position='100'
  141. error='false'
  142. numsubpods='1'
  143. primary='true'>
  144. <subpod title=''>
  145. <plaintext>∫1/xxlog(x)+constant</plaintext>
  146. </subpod>
  147. <states count='1'>
  148. <state name='Step-by-step solution'
  149. input='IndefiniteIntegral__Step-by-step solution' />
  150. </states>
  151. <infos count='1'>
  152. <info text='log(x) is the natural logarithm'>
  153. <link url='http://reference.wolfram.com/mathematica/ref/Log.html'
  154. text='Documentation'
  155. title='Mathematica' />
  156. <link url='http://functions.wolfram.com/ElementaryFunctions/Log'
  157. text='Properties'
  158. title='Wolfram Functions Site' />
  159. <link url='http://mathworld.wolfram.com/NaturalLogarithm.html'
  160. text='Definition'
  161. title='MathWorld' />
  162. </info>
  163. </infos>
  164. </pod>
  165. <pod title='Plots of the integral'
  166. scanner='Integral'
  167. id='Plot'
  168. position='200'
  169. error='false'
  170. numsubpods='2'>
  171. <subpod title=''>
  172. <plaintext></plaintext>
  173. <states count='1'>
  174. <statelist count='2'
  175. value='Complex-valued plot'
  176. delimiters=''>
  177. <state name='Complex-valued plot'
  178. input='Plot__1_Complex-valued plot' />
  179. <state name='Real-valued plot'
  180. input='Plot__1_Real-valued plot' />
  181. </statelist>
  182. </states>
  183. </subpod>
  184. <subpod title=''>
  185. <plaintext></plaintext>
  186. <states count='1'>
  187. <statelist count='2'
  188. value='Complex-valued plot'
  189. delimiters=''>
  190. <state name='Complex-valued plot'
  191. input='Plot__2_Complex-valued plot' />
  192. <state name='Real-valued plot'
  193. input='Plot__2_Real-valued plot' />
  194. </statelist>
  195. </states>
  196. </subpod>
  197. </pod>
  198. <assumptions count='1'>
  199. <assumption type='Clash'
  200. word='integral'
  201. template='Assuming &quot;${word}&quot; is ${desc1}. Use as ${desc2} instead'
  202. count='2'>
  203. <value name='IntegralsWord'
  204. desc='an integral'
  205. input='*C.integral-_*IntegralsWord-' />
  206. <value name='MathematicalFunctionIdentityPropertyClass'
  207. desc='a function property'
  208. input='*C.integral-_*MathematicalFunctionIdentityPropertyClass-' />
  209. </assumption>
  210. </assumptions>
  211. </queryresult>
  212. """
  213. # test integral
  214. response = mock.Mock(content=xml)
  215. results = wolframalpha_api.response(response)
  216. self.assertEqual(type(results), list)
  217. self.assertEqual(len(results), 1)
  218. self.assertIn('log(x)+c', results[0]['answer'])
  219. xml = """<?xml version='1.0' encoding='UTF-8'?>
  220. <queryresult success='true'
  221. error='false'
  222. numpods='4'
  223. datatypes='Solve'
  224. timedout=''
  225. timedoutpods=''
  226. timing='0.883'
  227. parsetiming='0.337'
  228. parsetimedout='false'
  229. recalculate=''
  230. id='MSPa347225h1ea85fgfbgb4000064ff000d25g5df3f'
  231. host='http://www5a.wolframalpha.com'
  232. server='52'
  233. related='http://www5a.wolframalpha.com/api/v2/relatedQueries.jsp?...'
  234. version='2.6'>
  235. <pod title='Input interpretation'
  236. scanner='Identity'
  237. id='Input'
  238. position='100'
  239. error='false'
  240. numsubpods='1'>
  241. <subpod title=''>
  242. <img src='http://www5a.wolframalpha.com/Calculate/MSP/MSP349225h1ea85fgfbgb400005dhd93b9eegg8f32?...'
  243. alt='solve x^2+x = 0'
  244. title='solve x^2+x = 0'
  245. width='157'
  246. height='35' />
  247. <plaintext>solve x^2+x = 0</plaintext>
  248. </subpod>
  249. </pod>
  250. <pod title='Results'
  251. scanner='Solve'
  252. id='Result'
  253. position='200'
  254. error='false'
  255. numsubpods='2'
  256. primary='true'>
  257. <subpod title=''>
  258. <img src='http://www5a.wolframalpha.com/Calculate/MSP/MSP350225h1ea85fgfbgb400005b1ebcefaha3ac97?...'
  259. alt='x = -1'
  260. title='x = -1'
  261. width='47'
  262. height='18' />
  263. <plaintext>x = -1</plaintext>
  264. </subpod>
  265. <subpod title=''>
  266. <img src='http://www5a.wolframalpha.com/Calculate/MSP/MSP351225h1ea85fgfbgb4000032fic0ig981hc936?...'
  267. alt='x = 0'
  268. title='x = 0'
  269. width='36'
  270. height='18' />
  271. <plaintext>x = 0</plaintext>
  272. </subpod>
  273. <states count='1'>
  274. <state name='Step-by-step solution'
  275. input='Result__Step-by-step solution' />
  276. </states>
  277. </pod>
  278. <pod title='Root plot'
  279. scanner='Solve'
  280. id='RootPlot'
  281. position='300'
  282. error='false'
  283. numsubpods='1'>
  284. <subpod title=''>
  285. <img src='http://www5a.wolframalpha.com/Calculate/MSP/MSP352225h1ea85fgfbgb40000464054c665hc5dee?...'
  286. alt=''
  287. title=''
  288. width='300'
  289. height='181' />
  290. <plaintext></plaintext>
  291. </subpod>
  292. </pod>
  293. <pod title='Number line'
  294. scanner='Solve'
  295. id='NumberLine'
  296. position='400'
  297. error='false'
  298. numsubpods='1'>
  299. <subpod title=''>
  300. <img src='http://www5a.wolframalpha.com/Calculate/MSP/MSP353225h1ea85fgfbgb400005ab1c8aai366fe46?...'
  301. alt=''
  302. title=''
  303. width='310'
  304. height='36' />
  305. <plaintext></plaintext>
  306. </subpod>
  307. </pod>
  308. </queryresult>
  309. """
  310. # test ecuation with multiple answers
  311. response = mock.Mock(content=xml)
  312. results = wolframalpha_api.response(response)
  313. self.assertEqual(type(results), list)
  314. self.assertEqual(len(results), 2)
  315. self.assertIn('x = -1', results[0]['answer'])
  316. self.assertIn('x = 0', results[1]['answer'])