omni_completer_test.py 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. # encoding: utf-8
  2. #
  3. # Copyright (C) 2016 YouCompleteMe contributors
  4. #
  5. # This file is part of YouCompleteMe.
  6. #
  7. # YouCompleteMe is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # YouCompleteMe is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
  19. from __future__ import unicode_literals
  20. from __future__ import print_function
  21. from __future__ import division
  22. from __future__ import absolute_import
  23. # Not installing aliases from python-future; it's unreliable and slow.
  24. from builtins import * # noqa
  25. from future.utils import PY2
  26. from mock import patch, call
  27. from nose.tools import eq_
  28. from hamcrest import contains_string
  29. from ycm.tests.test_utils import ExpectedFailure, ExtendedMock, MockVimModule
  30. MockVimModule()
  31. from ycm.tests import YouCompleteMeInstance
  32. from ycmd.utils import ToBytes
  33. from ycmd.request_wrap import RequestWrap
  34. def ToBytesOnPY2( data ):
  35. # To test the omnifunc, etc. returning strings, which can be of different
  36. # types depending on python version, we use ToBytes on PY2 and just the native
  37. # str on python3. This roughly matches what happens between py2 and py3
  38. # versions within Vim
  39. if PY2:
  40. return ToBytes( data )
  41. return data
  42. def BuildRequest( line_num, column_num, contents ):
  43. # Note: it would be nice to use ycmd.tests.test_utils.BuildRequest directly
  44. # here, but we can't import ycmd.tests.test_utils because that in turn imports
  45. # ycm_core, which would cause our "ycm_core not imported" test to fail.
  46. return {
  47. 'line_num': line_num,
  48. 'column_num': column_num,
  49. 'filepath': '/test',
  50. 'file_data': {
  51. '/test': {
  52. 'contents': contents,
  53. 'filetypes': [ 'java' ] # We need a filetype with a trigger, so we just
  54. # use java
  55. }
  56. }
  57. }
  58. def BuildRequestWrap( line_num, column_num, contents ):
  59. return RequestWrap( BuildRequest( line_num, column_num, contents ) )
  60. @YouCompleteMeInstance( { 'cache_omnifunc': 1 } )
  61. def OmniCompleter_GetCompletions_Cache_List_test( ycm ):
  62. contents = 'test.'
  63. request_data = BuildRequestWrap( line_num = 1,
  64. column_num = 6,
  65. contents = contents )
  66. # Make sure there is an omnifunc set up.
  67. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  68. ycm._omnicomp.OnFileReadyToParse( request_data )
  69. omnifunc_result = [ ToBytesOnPY2( 'a' ),
  70. ToBytesOnPY2( 'b' ),
  71. ToBytesOnPY2( 'cdef' ) ]
  72. # And get the completions
  73. with patch( 'vim.eval',
  74. new_callable = ExtendedMock,
  75. side_effect = [ 6, omnifunc_result ] ) as vim_eval:
  76. results = ycm._omnicomp.ComputeCandidates( request_data )
  77. vim_eval.assert_has_exact_calls( [
  78. call( 'test_omnifunc(1,"")' ),
  79. call( "test_omnifunc(0,'')" ),
  80. ] )
  81. eq_( results, omnifunc_result )
  82. @YouCompleteMeInstance( { 'cache_omnifunc': 1 } )
  83. def OmniCompleter_GetCompletions_Cache_ListFilter_test( ycm ):
  84. contents = 'test.t'
  85. request_data = BuildRequestWrap( line_num = 1,
  86. column_num = 7,
  87. contents = contents )
  88. eq_( request_data[ 'query' ], 't' )
  89. # Make sure there is an omnifunc set up.
  90. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  91. ycm._omnicomp.OnFileReadyToParse( request_data )
  92. omnifunc_result = [ ToBytesOnPY2( 'a' ),
  93. ToBytesOnPY2( 'b' ),
  94. ToBytesOnPY2( 'cdef' ) ]
  95. # And get the completions
  96. with patch( 'vim.eval',
  97. new_callable = ExtendedMock,
  98. side_effect = [ 6, omnifunc_result ] ) as vim_eval:
  99. results = ycm._omnicomp.ComputeCandidates( request_data )
  100. vim_eval.assert_has_exact_calls( [
  101. call( 'test_omnifunc(1,"")' ),
  102. call( "test_omnifunc(0,'t')" ),
  103. ] )
  104. eq_( results, [] )
  105. @YouCompleteMeInstance( { 'cache_omnifunc': 0 } )
  106. def OmniCompleter_GetCompletions_NoCache_List_test( ycm ):
  107. contents = 'test.'
  108. request_data = BuildRequestWrap( line_num = 1,
  109. column_num = 6,
  110. contents = contents )
  111. # Make sure there is an omnifunc set up.
  112. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  113. ycm._omnicomp.OnFileReadyToParse( request_data )
  114. omnifunc_result = [ ToBytesOnPY2( 'a' ),
  115. ToBytesOnPY2( 'b' ),
  116. ToBytesOnPY2( 'cdef' ) ]
  117. # And get the completions
  118. with patch( 'vim.eval',
  119. new_callable = ExtendedMock,
  120. side_effect = [ 6, omnifunc_result ] ) as vim_eval:
  121. results = ycm._omnicomp.ComputeCandidates( request_data )
  122. vim_eval.assert_has_exact_calls( [
  123. call( 'test_omnifunc(1,"")' ),
  124. call( "test_omnifunc(0,'')" ),
  125. ] )
  126. eq_( results, omnifunc_result )
  127. @YouCompleteMeInstance( { 'cache_omnifunc': 0 } )
  128. def OmniCompleter_GetCompletions_NoCache_ListFilter_test( ycm ):
  129. contents = 'test.t'
  130. request_data = BuildRequestWrap( line_num = 1,
  131. column_num = 7,
  132. contents = contents )
  133. eq_( request_data[ 'query' ], 't' )
  134. # Make sure there is an omnifunc set up.
  135. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  136. ycm._omnicomp.OnFileReadyToParse( request_data )
  137. omnifunc_result = [ ToBytesOnPY2( 'a' ),
  138. ToBytesOnPY2( 'b' ),
  139. ToBytesOnPY2( 'cdef' ) ]
  140. # And get the completions
  141. with patch( 'vim.eval',
  142. new_callable = ExtendedMock,
  143. side_effect = [ 6, omnifunc_result ] ) as vim_eval:
  144. results = ycm._omnicomp.ComputeCandidates( request_data )
  145. vim_eval.assert_has_exact_calls( [
  146. call( 'test_omnifunc(1,"")' ),
  147. call( "test_omnifunc(0,'t')" ),
  148. ] )
  149. # actual result is that the results are not filtered, as we expect the
  150. # omniufunc or vim itself to do this filtering
  151. eq_( results, omnifunc_result )
  152. @ExpectedFailure( 'We ignore the result of the call to findstart and use our '
  153. 'own interpretation of where the identifier should be',
  154. contains_string( "test_omnifunc(0,'t')" ) )
  155. @YouCompleteMeInstance( { 'cache_omnifunc': 1 } )
  156. def OmniCompleter_GetCompletsions_UseFindStart_test( ycm ):
  157. contents = 'test.t'
  158. request_data = BuildRequestWrap( line_num = 1,
  159. column_num = 7,
  160. contents = contents )
  161. eq_( request_data[ 'query' ], 't' )
  162. # Make sure there is an omnifunc set up.
  163. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  164. ycm._omnicomp.OnFileReadyToParse( request_data )
  165. omnifunc_result = [ ToBytesOnPY2( 'a' ),
  166. ToBytesOnPY2( 'b' ),
  167. ToBytesOnPY2( 'cdef' ) ]
  168. # And get the completions
  169. with patch( 'vim.eval',
  170. new_callable = ExtendedMock,
  171. side_effect = [ 1, omnifunc_result ] ) as vim_eval:
  172. results = ycm._omnicomp.ComputeCandidates( request_data )
  173. vim_eval.assert_has_exact_calls( [
  174. call( 'test_omnifunc(1,"")' ),
  175. # Fails here: actual result is that the findstart result (1) is ignored
  176. # and we use the 't' query as we normally would on the server side
  177. call( "test_omnifunc(0,'test.t')" ),
  178. ] )
  179. eq_( results, omnifunc_result )
  180. @YouCompleteMeInstance( { 'cache_omnifunc': 1 } )
  181. def OmniCompleter_GetCompletions_Cache_Object_test( ycm ):
  182. contents = 'test.t'
  183. request_data = BuildRequestWrap( line_num = 1,
  184. column_num = 7,
  185. contents = contents )
  186. eq_( request_data[ 'query' ], 't' )
  187. # Make sure there is an omnifunc set up.
  188. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  189. ycm._omnicomp.OnFileReadyToParse( request_data )
  190. omnifunc_result = {
  191. 'words': [
  192. ToBytesOnPY2( 'a' ),
  193. ToBytesOnPY2( 'b' ),
  194. ToBytesOnPY2( 'CDtEF' )
  195. ]
  196. }
  197. # And get the completions
  198. with patch( 'vim.eval',
  199. new_callable = ExtendedMock,
  200. side_effect = [ 6, omnifunc_result ] ) as vim_eval:
  201. results = ycm._omnicomp.ComputeCandidates( request_data )
  202. vim_eval.assert_has_exact_calls( [
  203. call( 'test_omnifunc(1,"")' ),
  204. call( "test_omnifunc(0,'t')" ),
  205. ] )
  206. eq_( results, [ ToBytesOnPY2( 'CDtEF' ) ] )
  207. @YouCompleteMeInstance( { 'cache_omnifunc': 1 } )
  208. def OmniCompleter_GetCompletions_Cache_ObjectList_test( ycm ):
  209. contents = 'test.tt'
  210. request_data = BuildRequestWrap( line_num = 1,
  211. column_num = 8,
  212. contents = contents )
  213. eq_( request_data[ 'query' ], 'tt' )
  214. # Make sure there is an omnifunc set up.
  215. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  216. ycm._omnicomp.OnFileReadyToParse( request_data )
  217. omnifunc_result = [
  218. {
  219. 'word': ToBytesOnPY2( 'a' ),
  220. 'abbr': ToBytesOnPY2( 'ABBR'),
  221. 'menu': ToBytesOnPY2( 'MENU' ),
  222. 'info': ToBytesOnPY2( 'INFO' ),
  223. 'kind': ToBytesOnPY2( 'K' )
  224. },
  225. {
  226. 'word': ToBytesOnPY2( 'test' ),
  227. 'abbr': ToBytesOnPY2( 'ABBRTEST'),
  228. 'menu': ToBytesOnPY2( 'MENUTEST' ),
  229. 'info': ToBytesOnPY2( 'INFOTEST' ),
  230. 'kind': ToBytesOnPY2( 'T' )
  231. }
  232. ]
  233. # And get the completions
  234. with patch( 'vim.eval',
  235. new_callable = ExtendedMock,
  236. side_effect = [ 6, omnifunc_result ] ) as vim_eval:
  237. results = ycm._omnicomp.ComputeCandidates( request_data )
  238. vim_eval.assert_has_exact_calls( [
  239. call( 'test_omnifunc(1,"")' ),
  240. call( "test_omnifunc(0,'tt')" ),
  241. ] )
  242. eq_( results, [ omnifunc_result[ 1 ] ] )
  243. @YouCompleteMeInstance( { 'cache_omnifunc': 0 } )
  244. def OmniCompleter_GetCompletions_NoCache_ObjectList_test( ycm ):
  245. contents = 'test.tt'
  246. request_data = BuildRequestWrap( line_num = 1,
  247. column_num = 8,
  248. contents = contents )
  249. eq_( request_data[ 'query' ], 'tt' )
  250. # Make sure there is an omnifunc set up.
  251. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  252. ycm._omnicomp.OnFileReadyToParse( request_data )
  253. omnifunc_result = [
  254. {
  255. 'word': ToBytesOnPY2( 'a' ),
  256. 'abbr': ToBytesOnPY2( 'ABBR'),
  257. 'menu': ToBytesOnPY2( 'MENU' ),
  258. 'info': ToBytesOnPY2( 'INFO' ),
  259. 'kind': ToBytesOnPY2( 'K' )
  260. },
  261. {
  262. 'word': ToBytesOnPY2( 'test' ),
  263. 'abbr': ToBytesOnPY2( 'ABBRTEST'),
  264. 'menu': ToBytesOnPY2( 'MENUTEST' ),
  265. 'info': ToBytesOnPY2( 'INFOTEST' ),
  266. 'kind': ToBytesOnPY2( 'T' )
  267. }
  268. ]
  269. # And get the completions
  270. with patch( 'vim.eval',
  271. new_callable = ExtendedMock,
  272. side_effect = [ 6, omnifunc_result ] ) as vim_eval:
  273. results = ycm._omnicomp.ComputeCandidates( request_data )
  274. vim_eval.assert_has_exact_calls( [
  275. call( 'test_omnifunc(1,"")' ),
  276. call( "test_omnifunc(0,'tt')" ),
  277. ] )
  278. # We don't filter the result - we expect the omnifunc to do that
  279. # based on the query we supplied (Note: that means no fuzzy matching!)
  280. eq_( results, omnifunc_result )
  281. @YouCompleteMeInstance( { 'cache_omnifunc': 1 } )
  282. def OmniCompleter_GetCompletions_Cache_ObjectListObject_test( ycm ):
  283. contents = 'test.tt'
  284. request_data = BuildRequestWrap( line_num = 1,
  285. column_num = 8,
  286. contents = contents )
  287. eq_( request_data[ 'query' ], 'tt' )
  288. # Make sure there is an omnifunc set up.
  289. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  290. ycm._omnicomp.OnFileReadyToParse( request_data )
  291. omnifunc_result = {
  292. 'words': [
  293. {
  294. 'word': ToBytesOnPY2( 'a' ),
  295. 'abbr': ToBytesOnPY2( 'ABBR'),
  296. 'menu': ToBytesOnPY2( 'MENU' ),
  297. 'info': ToBytesOnPY2( 'INFO' ),
  298. 'kind': ToBytesOnPY2( 'K' )
  299. },
  300. {
  301. 'word': ToBytesOnPY2( 'test' ),
  302. 'abbr': ToBytesOnPY2( 'ABBRTEST'),
  303. 'menu': ToBytesOnPY2( 'MENUTEST' ),
  304. 'info': ToBytesOnPY2( 'INFOTEST' ),
  305. 'kind': ToBytesOnPY2( 'T' )
  306. }
  307. ]
  308. }
  309. # And get the completions
  310. with patch( 'vim.eval',
  311. new_callable = ExtendedMock,
  312. side_effect = [ 6, omnifunc_result ] ) as vim_eval:
  313. results = ycm._omnicomp.ComputeCandidates( request_data )
  314. vim_eval.assert_has_exact_calls( [
  315. call( 'test_omnifunc(1,"")' ),
  316. call( "test_omnifunc(0,'tt')" ),
  317. ] )
  318. eq_( results, [ omnifunc_result[ 'words' ][ 1 ] ] )
  319. @YouCompleteMeInstance( { 'cache_omnifunc': 0 } )
  320. def OmniCompleter_GetCompletions_NoCache_ObjectListObject_test( ycm ):
  321. contents = 'test.tt'
  322. request_data = BuildRequestWrap( line_num = 1,
  323. column_num = 8,
  324. contents = contents )
  325. eq_( request_data[ 'query' ], 'tt' )
  326. # Make sure there is an omnifunc set up.
  327. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  328. ycm._omnicomp.OnFileReadyToParse( request_data )
  329. omnifunc_result = {
  330. 'words': [
  331. {
  332. 'word': ToBytesOnPY2( 'a' ),
  333. 'abbr': ToBytesOnPY2( 'ABBR'),
  334. 'menu': ToBytesOnPY2( 'MENU' ),
  335. 'info': ToBytesOnPY2( 'INFO' ),
  336. 'kind': ToBytesOnPY2( 'K' )
  337. },
  338. {
  339. 'word': ToBytesOnPY2( 'test' ),
  340. 'abbr': ToBytesOnPY2( 'ABBRTEST'),
  341. 'menu': ToBytesOnPY2( 'MENUTEST' ),
  342. 'info': ToBytesOnPY2( 'INFOTEST' ),
  343. 'kind': ToBytesOnPY2( 'T' )
  344. }
  345. ]
  346. }
  347. # And get the completions
  348. with patch( 'vim.eval',
  349. new_callable = ExtendedMock,
  350. side_effect = [ 6, omnifunc_result ] ) as vim_eval:
  351. results = ycm._omnicomp.ComputeCandidates( request_data )
  352. vim_eval.assert_has_exact_calls( [
  353. call( 'test_omnifunc(1,"")' ),
  354. call( "test_omnifunc(0,'tt')" ),
  355. ] )
  356. # No FilterAndSortCandidates for cache_omnifunc=0 (we expect the omnifunc
  357. # to do the filtering?)
  358. eq_( results, omnifunc_result[ 'words' ] )
  359. @YouCompleteMeInstance( { 'cache_omnifunc': 1 } )
  360. def OmniCompleter_GetCompletions_Cache_List_Unicode_test( ycm ):
  361. contents = '†åsty_π.'
  362. request_data = BuildRequestWrap( line_num = 1,
  363. column_num = 13,
  364. contents = contents )
  365. # Make sure there is an omnifunc set up.
  366. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  367. ycm._omnicomp.OnFileReadyToParse( request_data )
  368. omnifunc_result = [ ToBytesOnPY2( '†est' ),
  369. ToBytesOnPY2( 'å_unicode_identifier' ),
  370. ToBytesOnPY2( 'πππππππ yummy πie' ) ]
  371. # And get the completions
  372. with patch( 'vim.eval',
  373. new_callable = ExtendedMock,
  374. side_effect = [ 6, omnifunc_result ] ) as vim_eval:
  375. results = ycm._omnicomp.ComputeCandidates( request_data )
  376. vim_eval.assert_has_exact_calls( [
  377. call( 'test_omnifunc(1,"")' ),
  378. call( "test_omnifunc(0,'')" ),
  379. ] )
  380. eq_( results, omnifunc_result )
  381. @YouCompleteMeInstance( { 'cache_omnifunc': 1 } )
  382. def OmniCompleter_GetCompletions_NoCache_List_Unicode_test( ycm ):
  383. contents = '†åsty_π.'
  384. request_data = BuildRequestWrap( line_num = 1,
  385. column_num = 13,
  386. contents = contents )
  387. # Make sure there is an omnifunc set up.
  388. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  389. ycm._omnicomp.OnFileReadyToParse( request_data )
  390. omnifunc_result = [ ToBytesOnPY2( '†est' ),
  391. ToBytesOnPY2( 'å_unicode_identifier' ),
  392. ToBytesOnPY2( 'πππππππ yummy πie' ) ]
  393. # And get the completions
  394. with patch( 'vim.eval',
  395. new_callable = ExtendedMock,
  396. side_effect = [ 6, omnifunc_result ] ) as vim_eval:
  397. results = ycm._omnicomp.ComputeCandidates( request_data )
  398. vim_eval.assert_has_exact_calls( [
  399. call( 'test_omnifunc(1,"")' ),
  400. call( "test_omnifunc(0,'')" ),
  401. ] )
  402. eq_( results, omnifunc_result )
  403. @ExpectedFailure( 'Filtering on unicode is not supported by the server' )
  404. @YouCompleteMeInstance( { 'cache_omnifunc': 1 } )
  405. def OmniCompleter_GetCompletions_Cache_List_Filter_Unicode_test( ycm ):
  406. contents = '†åsty_π.ππ'
  407. request_data = BuildRequestWrap( line_num = 1,
  408. column_num = 17,
  409. contents = contents )
  410. # Make sure there is an omnifunc set up.
  411. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  412. ycm._omnicomp.OnFileReadyToParse( request_data )
  413. omnifunc_result = [ ToBytesOnPY2( '†est' ),
  414. ToBytesOnPY2( 'å_unicode_identifier' ),
  415. ToBytesOnPY2( 'πππππππ yummy πie' ) ]
  416. # And get the completions
  417. with patch( 'vim.eval',
  418. new_callable = ExtendedMock,
  419. side_effect = [ 6, omnifunc_result ] ) as vim_eval:
  420. results = ycm._omnicomp.ComputeCandidates( request_data )
  421. vim_eval.assert_has_exact_calls( [
  422. call( 'test_omnifunc(1,"")' ),
  423. call( "test_omnifunc(0,'ππ')" ),
  424. ] )
  425. # Fails here: Filtering on unicode is not supported
  426. eq_( results, [ omnifunc_result[ 2 ] ] )
  427. @YouCompleteMeInstance( { 'cache_omnifunc': 0 } )
  428. def OmniCompleter_GetCompletions_NoCache_List_Filter_Unicode_test( ycm ):
  429. contents = '†åsty_π.ππ'
  430. request_data = BuildRequestWrap( line_num = 1,
  431. column_num = 17,
  432. contents = contents )
  433. # Make sure there is an omnifunc set up.
  434. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  435. ycm._omnicomp.OnFileReadyToParse( request_data )
  436. omnifunc_result = [ ToBytesOnPY2( 'πππππππ yummy πie' ) ]
  437. # And get the completions
  438. with patch( 'vim.eval',
  439. new_callable = ExtendedMock,
  440. side_effect = [ 6, omnifunc_result ] ) as vim_eval:
  441. results = ycm._omnicomp.ComputeCandidates( request_data )
  442. vim_eval.assert_has_exact_calls( [
  443. call( 'test_omnifunc(1,"")' ),
  444. call( "test_omnifunc(0,'ππ')" ),
  445. ] )
  446. eq_( results, omnifunc_result )
  447. @ExpectedFailure( 'Filtering on unicode is not supported by the server' )
  448. @YouCompleteMeInstance( { 'cache_omnifunc': 1 } )
  449. def OmniCompleter_GetCompletions_Cache_ObjectList_Unicode_test( ycm ):
  450. contents = '†åsty_π.ππ'
  451. request_data = BuildRequestWrap( line_num = 1,
  452. column_num = 17,
  453. contents = contents )
  454. eq_( request_data[ 'query' ], 'ππ' )
  455. # Make sure there is an omnifunc set up.
  456. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  457. ycm._omnicomp.OnFileReadyToParse( request_data )
  458. omnifunc_result = [
  459. {
  460. 'word': ToBytesOnPY2( 'ålpha∫et' ),
  461. 'abbr': ToBytesOnPY2( 'å∫∫®'),
  462. 'menu': ToBytesOnPY2( 'µ´~¨á' ),
  463. 'info': ToBytesOnPY2( '^~fo' ),
  464. 'kind': ToBytesOnPY2( '˚' )
  465. },
  466. {
  467. 'word': ToBytesOnPY2( 'π†´ß†π' ),
  468. 'abbr': ToBytesOnPY2( 'ÅııÂʉÍÊ'),
  469. 'menu': ToBytesOnPY2( '˜‰ˆËʉÍÊ' ),
  470. 'info': ToBytesOnPY2( 'ȈÏØʉÍÊ' ),
  471. 'kind': ToBytesOnPY2( 'Ê' )
  472. }
  473. ]
  474. # And get the completions
  475. with patch( 'vim.eval',
  476. new_callable = ExtendedMock,
  477. side_effect = [ 6, omnifunc_result ] ) as vim_eval:
  478. results = ycm._omnicomp.ComputeCandidates( request_data )
  479. vim_eval.assert_has_exact_calls( [
  480. call( 'test_omnifunc(1,"")' ),
  481. call( "test_omnifunc(0,'ππ')" ),
  482. ] )
  483. # Fails here: Filtering on unicode is not supported
  484. eq_( results, [ omnifunc_result[ 1 ] ] )
  485. @YouCompleteMeInstance( { 'cache_omnifunc': 1 } )
  486. def OmniCompleter_GetCompletions_Cache_ObjectListObject_Unicode_test( ycm ):
  487. contents = '†åsty_π.t'
  488. request_data = BuildRequestWrap( line_num = 1,
  489. column_num = 14,
  490. contents = contents )
  491. eq_( request_data[ 'query' ], 't' )
  492. # Make sure there is an omnifunc set up.
  493. with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
  494. ycm._omnicomp.OnFileReadyToParse( request_data )
  495. omnifunc_result = {
  496. 'words': [
  497. {
  498. 'word': ToBytesOnPY2( 'ålpha∫et' ),
  499. 'abbr': ToBytesOnPY2( 'å∫∫®'),
  500. 'menu': ToBytesOnPY2( 'µ´~¨á' ),
  501. 'info': ToBytesOnPY2( '^~fo' ),
  502. 'kind': ToBytesOnPY2( '˚' )
  503. },
  504. {
  505. 'word': ToBytesOnPY2( 'π†´ß†π' ),
  506. 'abbr': ToBytesOnPY2( 'ÅııÂʉÍÊ'),
  507. 'menu': ToBytesOnPY2( '˜‰ˆËʉÍÊ' ),
  508. 'info': ToBytesOnPY2( 'ȈÏØʉÍÊ' ),
  509. 'kind': ToBytesOnPY2( 'Ê' )
  510. },
  511. {
  512. 'word': ToBytesOnPY2( 'test' ),
  513. 'abbr': ToBytesOnPY2( 'ÅııÂʉÍÊ'),
  514. 'menu': ToBytesOnPY2( '˜‰ˆËʉÍÊ' ),
  515. 'info': ToBytesOnPY2( 'ȈÏØʉÍÊ' ),
  516. 'kind': ToBytesOnPY2( 'Ê' )
  517. }
  518. ]
  519. }
  520. # And get the completions
  521. with patch( 'vim.eval',
  522. new_callable = ExtendedMock,
  523. side_effect = [ 6, omnifunc_result ] ) as vim_eval:
  524. results = ycm._omnicomp.ComputeCandidates( request_data )
  525. vim_eval.assert_has_exact_calls( [
  526. call( 'test_omnifunc(1,"")' ),
  527. call( "test_omnifunc(0,'t')" ),
  528. ] )
  529. # Note: the filtered results are all unicode objects (not bytes) because
  530. # they are passed through the FilterAndSortCandidates machinery
  531. # (via the server)
  532. eq_( results, [ {
  533. 'word': 'test',
  534. 'abbr': 'ÅııÂʉÍÊ',
  535. 'menu': '˜‰ˆËʉÍÊ',
  536. 'info': 'ȈÏØʉÍÊ',
  537. 'kind': 'Ê'
  538. } ] )