test_wolframalpha_api.py 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307
  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), 2)
  120. self.assertIn('i', results[0]['answer'])
  121. self.assertIn('sqrt(-1) - Wolfram|Alpha', results[1]['title'])
  122. self.assertEquals('http://www.wolframalpha.com/input/?i=sqrt%28-1%29', results[1]['url'])
  123. xml = """<?xml version='1.0' encoding='UTF-8'?>
  124. <queryresult success='true'
  125. error='false'
  126. numpods='2'
  127. datatypes=''
  128. timedout=''
  129. timedoutpods=''
  130. timing='1.286'
  131. parsetiming='0.255'
  132. parsetimedout='false'
  133. recalculate=''
  134. id='MSPa195222ad740ede5214h30000480ca61h003d3gd6'
  135. host='http://www3.wolframalpha.com'
  136. server='20'
  137. related='http://www3.wolframalpha.com/api/v2/relatedQueries.jsp?id=...'
  138. version='2.6'>
  139. <pod title='Indefinite integral'
  140. scanner='Integral'
  141. id='IndefiniteIntegral'
  142. position='100'
  143. error='false'
  144. numsubpods='1'
  145. primary='true'>
  146. <subpod title=''>
  147. <plaintext>∫1/xxlog(x)+constant</plaintext>
  148. </subpod>
  149. <states count='1'>
  150. <state name='Step-by-step solution'
  151. input='IndefiniteIntegral__Step-by-step solution' />
  152. </states>
  153. <infos count='1'>
  154. <info text='log(x) is the natural logarithm'>
  155. <link url='http://reference.wolfram.com/mathematica/ref/Log.html'
  156. text='Documentation'
  157. title='Mathematica' />
  158. <link url='http://functions.wolfram.com/ElementaryFunctions/Log'
  159. text='Properties'
  160. title='Wolfram Functions Site' />
  161. <link url='http://mathworld.wolfram.com/NaturalLogarithm.html'
  162. text='Definition'
  163. title='MathWorld' />
  164. </info>
  165. </infos>
  166. </pod>
  167. <pod title='Plots of the integral'
  168. scanner='Integral'
  169. id='Plot'
  170. position='200'
  171. error='false'
  172. numsubpods='2'>
  173. <subpod title=''>
  174. <plaintext></plaintext>
  175. <states count='1'>
  176. <statelist count='2'
  177. value='Complex-valued plot'
  178. delimiters=''>
  179. <state name='Complex-valued plot'
  180. input='Plot__1_Complex-valued plot' />
  181. <state name='Real-valued plot'
  182. input='Plot__1_Real-valued plot' />
  183. </statelist>
  184. </states>
  185. </subpod>
  186. <subpod title=''>
  187. <plaintext></plaintext>
  188. <states count='1'>
  189. <statelist count='2'
  190. value='Complex-valued plot'
  191. delimiters=''>
  192. <state name='Complex-valued plot'
  193. input='Plot__2_Complex-valued plot' />
  194. <state name='Real-valued plot'
  195. input='Plot__2_Real-valued plot' />
  196. </statelist>
  197. </states>
  198. </subpod>
  199. </pod>
  200. <assumptions count='1'>
  201. <assumption type='Clash'
  202. word='integral'
  203. template='Assuming &quot;${word}&quot; is ${desc1}. Use as ${desc2} instead'
  204. count='2'>
  205. <value name='IntegralsWord'
  206. desc='an integral'
  207. input='*C.integral-_*IntegralsWord-' />
  208. <value name='MathematicalFunctionIdentityPropertyClass'
  209. desc='a function property'
  210. input='*C.integral-_*MathematicalFunctionIdentityPropertyClass-' />
  211. </assumption>
  212. </assumptions>
  213. </queryresult>
  214. """
  215. # test integral
  216. response = mock.Mock(content=xml)
  217. results = wolframalpha_api.response(response)
  218. self.assertEqual(type(results), list)
  219. self.assertEqual(len(results), 2)
  220. self.assertIn('log(x)+c', results[0]['answer'])
  221. self.assertIn('∫1/xx - Wolfram|Alpha'.decode('utf-8'), results[1]['title'])
  222. self.assertEquals('http://www.wolframalpha.com/input/?i=%E2%88%AB1%2Fx%EF%9D%8Cx', results[1]['url'])
  223. xml = """<?xml version='1.0' encoding='UTF-8'?>
  224. <queryresult success='true'
  225. error='false'
  226. numpods='4'
  227. datatypes='Solve'
  228. timedout=''
  229. timedoutpods=''
  230. timing='0.79'
  231. parsetiming='0.338'
  232. parsetimedout='false'
  233. recalculate=''
  234. id='MSPa7481f7i06d25h3deh2900004810i3a78d9b4fdc'
  235. host='http://www5b.wolframalpha.com'
  236. server='23'
  237. related='http://www5b.wolframalpha.com/api/v2/relatedQueries.jsp?id=...'
  238. version='2.6'>
  239. <pod title='Input interpretation'
  240. scanner='Identity'
  241. id='Input'
  242. position='100'
  243. error='false'
  244. numsubpods='1'>
  245. <subpod title=''>
  246. <plaintext>solve x^2+x0</plaintext>
  247. </subpod>
  248. </pod>
  249. <pod title='Results'
  250. scanner='Solve'
  251. id='Result'
  252. position='200'
  253. error='false'
  254. numsubpods='2'
  255. primary='true'>
  256. <subpod title=''>
  257. <plaintext>x-1</plaintext>
  258. </subpod>
  259. <subpod title=''>
  260. <plaintext>x0</plaintext>
  261. </subpod>
  262. <states count='1'>
  263. <state name='Step-by-step solution'
  264. input='Result__Step-by-step solution' />
  265. </states>
  266. </pod>
  267. <pod title='Root plot'
  268. scanner='Solve'
  269. id='RootPlot'
  270. position='300'
  271. error='false'
  272. numsubpods='1'>
  273. <subpod title=''>
  274. <plaintext></plaintext>
  275. </subpod>
  276. </pod>
  277. <pod title='Number line'
  278. scanner='Solve'
  279. id='NumberLine'
  280. position='400'
  281. error='false'
  282. numsubpods='1'>
  283. <subpod title=''>
  284. <plaintext></plaintext>
  285. </subpod>
  286. </pod>
  287. </queryresult>
  288. """
  289. # test ecuation with multiple answers
  290. response = mock.Mock(content=xml)
  291. results = wolframalpha_api.response(response)
  292. self.assertEqual(type(results), list)
  293. self.assertEqual(len(results), 3)
  294. self.assertIn('x=-1', results[0]['answer'])
  295. self.assertIn('x=0', results[1]['answer'])
  296. self.assertIn('solve x^2+x0 - Wolfram|Alpha'.decode('utf-8'), results[2]['title'])
  297. self.assertEquals('http://www.wolframalpha.com/input/?i=solve+x%5E2%2Bx%EF%9F%990', results[2]['url'])