omni_completer_test.py 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953
  1. # encoding: utf-8
  2. #
  3. # Copyright (C) 2016-2019 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 hamcrest import assert_that, contains_exactly, empty, has_entries
  20. from unittest import TestCase
  21. from ycm.tests.test_utils import MockVimBuffers, MockVimModule, VimBuffer
  22. MockVimModule()
  23. from ycm import vimsupport
  24. from ycm.tests import YouCompleteMeInstance, youcompleteme_instance
  25. FILETYPE = 'ycmtest'
  26. TRIGGERS = {
  27. 'ycmtest': [ '.' ]
  28. }
  29. def StartColumnCompliance( ycm,
  30. omnifunc_start_column,
  31. ycm_completions,
  32. ycm_start_column ):
  33. def Omnifunc( findstart, base ):
  34. if findstart:
  35. return omnifunc_start_column
  36. return [ 'foo' ]
  37. current_buffer = VimBuffer( 'buffer',
  38. contents = [ 'fo' ],
  39. filetype = FILETYPE,
  40. omnifunc = Omnifunc )
  41. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 2 ) ):
  42. ycm.SendCompletionRequest( force_semantic = True )
  43. r = ycm.GetCompletionResponse()
  44. assert_that(
  45. r,
  46. has_entries( {
  47. 'completions': ycm_completions,
  48. 'completion_start_column': ycm_start_column
  49. } )
  50. )
  51. class OmniCompleterTest( TestCase ):
  52. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
  53. 'g:ycm_semantic_triggers': TRIGGERS } )
  54. def test_OmniCompleter_GetCompletions_Cache_List( self, ycm ):
  55. def Omnifunc( findstart, base ):
  56. if findstart:
  57. return 5
  58. return [ 'a', 'b', 'cdef' ]
  59. current_buffer = VimBuffer( 'buffer',
  60. contents = [ 'test.' ],
  61. filetype = FILETYPE,
  62. omnifunc = Omnifunc )
  63. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 5 ) ):
  64. ycm.SendCompletionRequest()
  65. assert_that(
  66. ycm.GetCompletionResponse(),
  67. has_entries( {
  68. 'completions': [
  69. { 'word': 'a', 'equal': 1 },
  70. { 'word': 'b', 'equal': 1 },
  71. { 'word': 'cdef', 'equal': 1 }
  72. ],
  73. 'completion_start_column': 6
  74. } )
  75. )
  76. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
  77. 'g:ycm_semantic_triggers': TRIGGERS } )
  78. def test_OmniCompleter_GetCompletions_Cache_ListFilter( self, ycm ):
  79. def Omnifunc( findstart, base ):
  80. if findstart:
  81. return 5
  82. return [ 'a', 'b', 'cdef' ]
  83. current_buffer = VimBuffer( 'buffer',
  84. contents = [ 'test.t' ],
  85. filetype = FILETYPE,
  86. omnifunc = Omnifunc )
  87. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
  88. ycm.SendCompletionRequest()
  89. assert_that(
  90. ycm.GetCompletionResponse(),
  91. has_entries( {
  92. 'completions': empty(),
  93. 'completion_start_column': 6
  94. } )
  95. )
  96. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
  97. 'g:ycm_semantic_triggers': TRIGGERS } )
  98. def test_OmniCompleter_GetCompletions_NoCache_List( self, ycm ):
  99. def Omnifunc( findstart, base ):
  100. if findstart:
  101. return 5
  102. return [ 'a', 'b', 'cdef' ]
  103. current_buffer = VimBuffer( 'buffer',
  104. contents = [ 'test.' ],
  105. filetype = FILETYPE,
  106. omnifunc = Omnifunc )
  107. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 5 ) ):
  108. ycm.SendCompletionRequest()
  109. assert_that(
  110. ycm.GetCompletionResponse(),
  111. has_entries( {
  112. 'completions': [
  113. { 'word': 'a', 'equal': 1 },
  114. { 'word': 'b', 'equal': 1 },
  115. { 'word': 'cdef', 'equal': 1 }
  116. ],
  117. 'completion_start_column': 6
  118. } )
  119. )
  120. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
  121. 'g:ycm_semantic_triggers': TRIGGERS } )
  122. def test_OmniCompleter_GetCompletions_NoCache_ListFilter( self, ycm ):
  123. def Omnifunc( findstart, base ):
  124. if findstart:
  125. return 5
  126. return [ 'a', 'b', 'cdef' ]
  127. current_buffer = VimBuffer( 'buffer',
  128. contents = [ 'test.t' ],
  129. filetype = FILETYPE,
  130. omnifunc = Omnifunc )
  131. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
  132. ycm.SendCompletionRequest()
  133. # Actual result is that the results are not filtered, as we expect the
  134. # omnifunc or vim itself to do this filtering.
  135. assert_that(
  136. ycm.GetCompletionResponse(),
  137. has_entries( {
  138. 'completions': [
  139. { 'word': 'a', 'equal': 1 },
  140. { 'word': 'b', 'equal': 1 },
  141. { 'word': 'cdef', 'equal': 1 }
  142. ],
  143. 'completion_start_column': 6
  144. } )
  145. )
  146. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
  147. 'g:ycm_semantic_triggers': TRIGGERS } )
  148. def test_OmniCompleter_GetCompletions_NoCache_UseFindStart( self, ycm ):
  149. def Omnifunc( findstart, base ):
  150. if findstart:
  151. return 0
  152. return [ 'a', 'b', 'cdef' ]
  153. current_buffer = VimBuffer( 'buffer',
  154. contents = [ 'test.t' ],
  155. filetype = FILETYPE,
  156. omnifunc = Omnifunc )
  157. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
  158. ycm.SendCompletionRequest()
  159. # Actual result is that the results are not filtered, as we expect the
  160. # omnifunc or vim itself to do this filtering.
  161. assert_that(
  162. ycm.GetCompletionResponse(),
  163. has_entries( {
  164. 'completions': [
  165. { 'word': 'a', 'equal': 1 },
  166. { 'word': 'b', 'equal': 1 },
  167. { 'word': 'cdef', 'equal': 1 }
  168. ],
  169. 'completion_start_column': 1
  170. } )
  171. )
  172. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
  173. 'g:ycm_semantic_triggers': TRIGGERS } )
  174. def test_OmniCompleter_GetCompletions_Cache_UseFindStart( self, ycm ):
  175. def Omnifunc( findstart, base ):
  176. if findstart:
  177. return 0
  178. return [ 'a', 'b', 'cdef' ]
  179. current_buffer = VimBuffer( 'buffer',
  180. contents = [ 'test.t' ],
  181. filetype = FILETYPE,
  182. omnifunc = Omnifunc )
  183. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
  184. ycm.SendCompletionRequest()
  185. # There are no results because the query 'test.t' doesn't match any
  186. # candidate (and cache_omnifunc=1, so we FilterAndSortCandidates).
  187. assert_that(
  188. ycm.GetCompletionResponse(),
  189. has_entries( {
  190. 'completions': empty(),
  191. 'completion_start_column': 1
  192. } )
  193. )
  194. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
  195. 'g:ycm_semantic_triggers': TRIGGERS } )
  196. def test_OmniCompleter_GetCompletions_Cache_Object( self, ycm ):
  197. def Omnifunc( findstart, base ):
  198. if findstart:
  199. return 5
  200. return { 'words': [ 'a', 'b', 'CDtEF' ] }
  201. current_buffer = VimBuffer( 'buffer',
  202. contents = [ 'test.t' ],
  203. filetype = FILETYPE,
  204. omnifunc = Omnifunc )
  205. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
  206. ycm.SendCompletionRequest()
  207. assert_that(
  208. ycm.GetCompletionResponse(),
  209. has_entries( {
  210. 'completions': [ { 'word': 'CDtEF', 'equal': 1 } ],
  211. 'completion_start_column': 6
  212. } )
  213. )
  214. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
  215. 'g:ycm_semantic_triggers': TRIGGERS } )
  216. def test_OmniCompleter_GetCompletions_Cache_ObjectList( self, ycm ):
  217. def Omnifunc( findstart, base ):
  218. if findstart:
  219. return 5
  220. return [
  221. {
  222. 'word': 'a',
  223. 'abbr': 'ABBR',
  224. 'menu': 'MENU',
  225. 'info': 'INFO',
  226. 'kind': 'K'
  227. },
  228. {
  229. 'word': 'test',
  230. 'abbr': 'ABBRTEST',
  231. 'menu': 'MENUTEST',
  232. 'info': 'INFOTEST',
  233. 'kind': 'T'
  234. }
  235. ]
  236. current_buffer = VimBuffer( 'buffer',
  237. contents = [ 'test.tt' ],
  238. filetype = FILETYPE,
  239. omnifunc = Omnifunc )
  240. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
  241. ycm.SendCompletionRequest()
  242. assert_that(
  243. ycm.GetCompletionResponse(),
  244. has_entries( {
  245. 'completions': contains_exactly( {
  246. 'word' : 'test',
  247. 'abbr' : 'ABBRTEST',
  248. 'menu' : 'MENUTEST',
  249. 'info' : 'INFOTEST',
  250. 'kind' : 'T',
  251. 'equal': 1
  252. } ),
  253. 'completion_start_column': 6
  254. } )
  255. )
  256. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
  257. 'g:ycm_semantic_triggers': TRIGGERS } )
  258. def test_OmniCompleter_GetCompletions_NoCache_ObjectList( self, ycm ):
  259. def Omnifunc( findstart, base ):
  260. if findstart:
  261. return 5
  262. return [
  263. {
  264. 'word': 'a',
  265. 'abbr': 'ABBR',
  266. 'menu': 'MENU',
  267. 'info': 'INFO',
  268. 'kind': 'K'
  269. },
  270. {
  271. 'word': 'test',
  272. 'abbr': 'ABBRTEST',
  273. 'menu': 'MENUTEST',
  274. 'info': 'INFOTEST',
  275. 'kind': 'T'
  276. }
  277. ]
  278. current_buffer = VimBuffer( 'buffer',
  279. contents = [ 'test.tt' ],
  280. filetype = FILETYPE,
  281. omnifunc = Omnifunc )
  282. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
  283. ycm.SendCompletionRequest()
  284. # We don't filter the result - we expect the omnifunc to do that
  285. # based on the query we supplied (Note: that means no fuzzy matching!).
  286. assert_that(
  287. ycm.GetCompletionResponse(),
  288. has_entries( {
  289. 'completions': [ {
  290. 'word' : 'a',
  291. 'abbr' : 'ABBR',
  292. 'menu' : 'MENU',
  293. 'info' : 'INFO',
  294. 'kind' : 'K',
  295. 'equal': 1
  296. }, {
  297. 'word' : 'test',
  298. 'abbr' : 'ABBRTEST',
  299. 'menu' : 'MENUTEST',
  300. 'info' : 'INFOTEST',
  301. 'kind' : 'T',
  302. 'equal': 1
  303. } ],
  304. 'completion_start_column': 6
  305. } )
  306. )
  307. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
  308. 'g:ycm_semantic_triggers': TRIGGERS } )
  309. def test_OmniCompleter_GetCompletions_Cache_ObjectListObject( self, ycm ):
  310. def Omnifunc( findstart, base ):
  311. if findstart:
  312. return 5
  313. return { 'words': [
  314. {
  315. 'word': 'a',
  316. 'abbr': 'ABBR',
  317. 'menu': 'MENU',
  318. 'info': 'INFO',
  319. 'kind': 'K'
  320. },
  321. {
  322. 'word': 'test',
  323. 'abbr': 'ABBRTEST',
  324. 'menu': 'MENUTEST',
  325. 'info': 'INFOTEST',
  326. 'kind': 'T'
  327. }
  328. ] }
  329. current_buffer = VimBuffer( 'buffer',
  330. contents = [ 'test.tt' ],
  331. filetype = FILETYPE,
  332. omnifunc = Omnifunc )
  333. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
  334. ycm.SendCompletionRequest()
  335. assert_that(
  336. ycm.GetCompletionResponse(),
  337. has_entries( {
  338. 'completions': [ {
  339. 'word' : 'test',
  340. 'abbr' : 'ABBRTEST',
  341. 'menu' : 'MENUTEST',
  342. 'info' : 'INFOTEST',
  343. 'kind' : 'T',
  344. 'equal': 1
  345. } ],
  346. 'completion_start_column': 6
  347. } )
  348. )
  349. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
  350. 'g:ycm_semantic_triggers': TRIGGERS } )
  351. def test_OmniCompleter_GetCompletions_NoCache_ObjectListObject( self, ycm ):
  352. def Omnifunc( findstart, base ):
  353. if findstart:
  354. return 5
  355. return { 'words': [
  356. {
  357. 'word': 'a',
  358. 'abbr': 'ABBR',
  359. 'menu': 'MENU',
  360. 'info': 'INFO',
  361. 'kind': 'K'
  362. },
  363. {
  364. 'word': 'test',
  365. 'abbr': 'ABBRTEST',
  366. 'menu': 'MENUTEST',
  367. 'info': 'INFOTEST',
  368. 'kind': 'T'
  369. }
  370. ] }
  371. current_buffer = VimBuffer( 'buffer',
  372. contents = [ 'test.tt' ],
  373. filetype = FILETYPE,
  374. omnifunc = Omnifunc )
  375. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
  376. ycm.SendCompletionRequest()
  377. # No FilterAndSortCandidates for cache_omnifunc=0 (we expect the omnifunc
  378. # to do the filtering?)
  379. assert_that(
  380. ycm.GetCompletionResponse(),
  381. has_entries( {
  382. 'completions': [ {
  383. 'word' : 'a',
  384. 'abbr' : 'ABBR',
  385. 'menu' : 'MENU',
  386. 'info' : 'INFO',
  387. 'kind' : 'K',
  388. 'equal': 1
  389. }, {
  390. 'word' : 'test',
  391. 'abbr' : 'ABBRTEST',
  392. 'menu' : 'MENUTEST',
  393. 'info' : 'INFOTEST',
  394. 'kind' : 'T',
  395. 'equal': 1
  396. } ],
  397. 'completion_start_column': 6
  398. } )
  399. )
  400. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
  401. 'g:ycm_semantic_triggers': TRIGGERS } )
  402. def test_OmniCompleter_GetCompletions_Cache_List_Unicode( self, ycm ):
  403. def Omnifunc( findstart, base ):
  404. if findstart:
  405. return 12
  406. return [ '†est', 'å_unicode_identifier', 'πππππππ yummy πie' ]
  407. current_buffer = VimBuffer( 'buffer',
  408. contents = [ '†åsty_π.' ],
  409. filetype = FILETYPE,
  410. omnifunc = Omnifunc )
  411. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 12 ) ):
  412. ycm.SendCompletionRequest()
  413. assert_that(
  414. ycm.GetCompletionResponse(),
  415. has_entries( {
  416. 'completions': [
  417. { 'word': 'å_unicode_identifier', 'equal': 1 },
  418. { 'word': 'πππππππ yummy πie', 'equal': 1 },
  419. { 'word': '†est', 'equal': 1 }
  420. ],
  421. 'completion_start_column': 13
  422. } )
  423. )
  424. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
  425. 'g:ycm_semantic_triggers': TRIGGERS } )
  426. def test_OmniCompleter_GetCompletions_NoCache_List_Unicode( self, ycm ):
  427. def Omnifunc( findstart, base ):
  428. if findstart:
  429. return 12
  430. return [ '†est', 'å_unicode_identifier', 'πππππππ yummy πie' ]
  431. current_buffer = VimBuffer( 'buffer',
  432. contents = [ '†åsty_π.' ],
  433. filetype = FILETYPE,
  434. omnifunc = Omnifunc )
  435. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 12 ) ):
  436. ycm.SendCompletionRequest()
  437. assert_that(
  438. ycm.GetCompletionResponse(),
  439. has_entries( {
  440. 'completions': [
  441. { 'word': '†est', 'equal': 1 },
  442. { 'word': 'å_unicode_identifier', 'equal': 1 },
  443. { 'word': 'πππππππ yummy πie', 'equal': 1 }
  444. ],
  445. 'completion_start_column': 13
  446. } )
  447. )
  448. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
  449. 'g:ycm_semantic_triggers': TRIGGERS } )
  450. def test_OmniCompleter_GetCompletions_Cache_List_Filter_Unicode( self, ycm ):
  451. def Omnifunc( findstart, base ):
  452. if findstart:
  453. return 12
  454. return [ '†est', 'å_unicode_identifier', 'πππππππ yummy πie' ]
  455. current_buffer = VimBuffer( 'buffer',
  456. contents = [ '†åsty_π.ππ' ],
  457. filetype = FILETYPE,
  458. omnifunc = Omnifunc )
  459. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 17 ) ):
  460. ycm.SendCompletionRequest()
  461. assert_that(
  462. ycm.GetCompletionResponse(),
  463. has_entries( {
  464. 'completions': [ { 'word': 'πππππππ yummy πie', 'equal': 1 } ],
  465. 'completion_start_column': 13
  466. } )
  467. )
  468. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
  469. 'g:ycm_semantic_triggers': TRIGGERS } )
  470. def test_OmniCompleter_GetCompletions_NoCache_List_Filter_Unicode(
  471. self, ycm ):
  472. def Omnifunc( findstart, base ):
  473. if findstart:
  474. return 12
  475. return [ 'πππππππ yummy πie' ]
  476. current_buffer = VimBuffer( 'buffer',
  477. contents = [ '†åsty_π.ππ' ],
  478. filetype = FILETYPE,
  479. omnifunc = Omnifunc )
  480. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 17 ) ):
  481. ycm.SendCompletionRequest()
  482. assert_that(
  483. ycm.GetCompletionResponse(),
  484. has_entries( {
  485. 'completions': [ { 'word': 'πππππππ yummy πie', 'equal': 1 } ],
  486. 'completion_start_column': 13
  487. } )
  488. )
  489. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
  490. 'g:ycm_semantic_triggers': TRIGGERS } )
  491. def test_OmniCompleter_GetCompletions_Cache_ObjectList_Unicode( self, ycm ):
  492. def Omnifunc( findstart, base ):
  493. if findstart:
  494. return 12
  495. return [
  496. {
  497. 'word': 'ålpha∫et',
  498. 'abbr': 'å∫∫®',
  499. 'menu': 'µ´~¨á',
  500. 'info': '^~fo',
  501. 'kind': '˚'
  502. },
  503. {
  504. 'word': 'π†´ß†π',
  505. 'abbr': 'ÅııÂʉÍÊ',
  506. 'menu': '˜‰ˆËʉÍÊ',
  507. 'info': 'ȈÏØʉÍÊ',
  508. 'kind': 'Ê'
  509. }
  510. ]
  511. current_buffer = VimBuffer( 'buffer',
  512. contents = [ '†åsty_π.ππ' ],
  513. filetype = FILETYPE,
  514. omnifunc = Omnifunc )
  515. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 17 ) ):
  516. ycm.SendCompletionRequest()
  517. assert_that(
  518. ycm.GetCompletionResponse(),
  519. has_entries( {
  520. 'completions': [ {
  521. 'word' : 'π†´ß†π',
  522. 'abbr' : 'ÅııÂʉÍÊ',
  523. 'menu' : '˜‰ˆËʉÍÊ',
  524. 'info' : 'ȈÏØʉÍÊ',
  525. 'kind' : 'Ê',
  526. 'equal': 1
  527. } ],
  528. 'completion_start_column': 13
  529. } )
  530. )
  531. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
  532. 'g:ycm_semantic_triggers': TRIGGERS } )
  533. def test_OmniCompleter_GetCompletions_Cache_ObjectListObject_Unicode(
  534. self, ycm ):
  535. def Omnifunc( findstart, base ):
  536. if findstart:
  537. return 12
  538. return {
  539. 'words': [
  540. {
  541. 'word': 'ålpha∫et',
  542. 'abbr': 'å∫∫®',
  543. 'menu': 'µ´~¨á',
  544. 'info': '^~fo',
  545. 'kind': '˚'
  546. },
  547. {
  548. 'word': 'π†´ß†π',
  549. 'abbr': 'ÅııÂʉÍÊ',
  550. 'menu': '˜‰ˆËʉÍÊ',
  551. 'info': 'ȈÏØʉÍÊ',
  552. 'kind': 'Ê'
  553. },
  554. {
  555. 'word': 'test',
  556. 'abbr': 'ÅııÂʉÍÊ',
  557. 'menu': '˜‰ˆËʉÍÊ',
  558. 'info': 'ȈÏØʉÍÊ',
  559. 'kind': 'Ê'
  560. }
  561. ]
  562. }
  563. current_buffer = VimBuffer( 'buffer',
  564. contents = [ '†åsty_π.t' ],
  565. filetype = FILETYPE,
  566. omnifunc = Omnifunc )
  567. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 13 ) ):
  568. ycm.SendCompletionRequest()
  569. assert_that(
  570. ycm.GetCompletionResponse(),
  571. has_entries( {
  572. 'completions': contains_exactly( {
  573. 'word' : 'test',
  574. 'abbr' : 'ÅııÂʉÍÊ',
  575. 'menu' : '˜‰ˆËʉÍÊ',
  576. 'info' : 'ȈÏØʉÍÊ',
  577. 'kind' : 'Ê',
  578. 'equal': 1
  579. }, {
  580. 'word' : 'ålpha∫et',
  581. 'abbr' : 'å∫∫®',
  582. 'menu' : 'µ´~¨á',
  583. 'info' : '^~fo',
  584. 'kind' : '˚',
  585. 'equal': 1
  586. } ),
  587. 'completion_start_column': 13
  588. } )
  589. )
  590. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
  591. 'g:ycm_semantic_triggers': TRIGGERS } )
  592. def test_OmniCompleter_GetCompletions_RestoreCursorPositionAfterOmnifuncCall(
  593. self, ycm ):
  594. # This omnifunc moves the cursor to the test definition like
  595. # ccomplete#Complete would.
  596. def Omnifunc( findstart, base ):
  597. vimsupport.SetCurrentLineAndColumn( 0, 0 )
  598. if findstart:
  599. return 5
  600. return [ 'length' ]
  601. current_buffer = VimBuffer( 'buffer',
  602. contents = [ 'String test',
  603. '',
  604. 'test.' ],
  605. filetype = FILETYPE,
  606. omnifunc = Omnifunc )
  607. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 3, 5 ) ):
  608. ycm.SendCompletionRequest()
  609. assert_that(
  610. vimsupport.CurrentLineAndColumn(),
  611. contains_exactly( 2, 5 )
  612. )
  613. assert_that(
  614. ycm.GetCompletionResponse(),
  615. has_entries( {
  616. 'completions': [ { 'word': 'length', 'equal': 1 } ],
  617. 'completion_start_column': 6
  618. } )
  619. )
  620. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
  621. 'g:ycm_semantic_triggers': TRIGGERS } )
  622. def test_OmniCompleter_GetCompletions_MoveCursorPositionAtStartColumn(
  623. self, ycm ):
  624. # This omnifunc relies on the cursor being moved at the start column when
  625. # called the second time like LanguageClient#complete from the
  626. # LanguageClient-neovim plugin.
  627. def Omnifunc( findstart, base ):
  628. if findstart:
  629. return 5
  630. if vimsupport.CurrentColumn() == 5:
  631. return [ 'length' ]
  632. return []
  633. current_buffer = VimBuffer( 'buffer',
  634. contents = [ 'String test',
  635. '',
  636. 'test.le' ],
  637. filetype = FILETYPE,
  638. omnifunc = Omnifunc )
  639. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 3, 7 ) ):
  640. ycm.SendCompletionRequest()
  641. assert_that(
  642. vimsupport.CurrentLineAndColumn(),
  643. contains_exactly( 2, 7 )
  644. )
  645. assert_that(
  646. ycm.GetCompletionResponse(),
  647. has_entries( {
  648. 'completions': [ { 'word': 'length', 'equal': 1 } ],
  649. 'completion_start_column': 6
  650. } )
  651. )
  652. def test_OmniCompleter_GetCompletions_StartColumnCompliance( self ):
  653. for omnifunc_start_column, ycm_completions, ycm_start_column in [
  654. [ -4, [ { 'word': 'foo', 'equal': 1 } ], 3 ],
  655. [ -3, [], 1 ],
  656. [ -2, [], 1 ],
  657. [ -1, [ { 'word': 'foo', 'equal': 1 } ], 3 ],
  658. [ 0, [ { 'word': 'foo', 'equal': 1 } ], 1 ],
  659. [ 1, [ { 'word': 'foo', 'equal': 1 } ], 2 ],
  660. [ 2, [ { 'word': 'foo', 'equal': 1 } ], 3 ],
  661. [ 3, [ { 'word': 'foo', 'equal': 1 } ], 3 ]
  662. ]:
  663. with youcompleteme_instance( { 'g:ycm_cache_omnifunc': 1 } ) as ycm:
  664. with self.subTest( omnifunc_start_column = omnifunc_start_column,
  665. ycm_completions = ycm_completions,
  666. ycm_start_column = ycm_start_column ):
  667. StartColumnCompliance( ycm,
  668. omnifunc_start_column,
  669. ycm_completions,
  670. ycm_start_column )
  671. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
  672. 'g:ycm_semantic_triggers': TRIGGERS } )
  673. def test_OmniCompleter_GetCompletions_NoCache_NoSemanticTrigger( self, ycm ):
  674. def Omnifunc( findstart, base ):
  675. if findstart:
  676. return 0
  677. return [ 'test' ]
  678. current_buffer = VimBuffer( 'buffer',
  679. contents = [ 'te' ],
  680. filetype = FILETYPE,
  681. omnifunc = Omnifunc )
  682. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 3 ) ):
  683. ycm.SendCompletionRequest()
  684. assert_that(
  685. ycm.GetCompletionResponse(),
  686. has_entries( {
  687. 'completions': empty(),
  688. 'completion_start_column': 1
  689. } )
  690. )
  691. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
  692. 'g:ycm_semantic_triggers': TRIGGERS } )
  693. def test_OmniCompleter_GetCompletions_NoCache_ForceSemantic( self, ycm ):
  694. def Omnifunc( findstart, base ):
  695. if findstart:
  696. return 0
  697. return [ 'test' ]
  698. current_buffer = VimBuffer( 'buffer',
  699. contents = [ 'te' ],
  700. filetype = FILETYPE,
  701. omnifunc = Omnifunc )
  702. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 3 ) ):
  703. ycm.SendCompletionRequest( force_semantic = True )
  704. assert_that(
  705. ycm.GetCompletionResponse(),
  706. has_entries( {
  707. 'completions': [ { 'word': 'test', 'equal': 1 } ],
  708. 'completion_start_column': 1
  709. } )
  710. )
  711. @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
  712. 'g:ycm_semantic_triggers': TRIGGERS } )
  713. def test_OmniCompleter_GetCompletions_ConvertStringsToDictionaries(
  714. self, ycm ):
  715. def Omnifunc( findstart, base ):
  716. if findstart:
  717. return 5
  718. return [
  719. { 'word': 'a' },
  720. 'b'
  721. ]
  722. current_buffer = VimBuffer( 'buffer',
  723. contents = [ 'test.' ],
  724. filetype = FILETYPE,
  725. omnifunc = Omnifunc )
  726. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
  727. ycm.SendCompletionRequest()
  728. assert_that(
  729. ycm.GetCompletionResponse(),
  730. has_entries( {
  731. 'completions': [
  732. { 'word': 'a', 'equal': 1 },
  733. { 'word': 'b', 'equal': 1 }
  734. ],
  735. 'completion_start_column': 6
  736. } )
  737. )
  738. @YouCompleteMeInstance( {
  739. 'g:ycm_cache_omnifunc': 0,
  740. 'g:ycm_filetype_specific_completion_to_disable': { FILETYPE: 1 },
  741. 'g:ycm_semantic_triggers': TRIGGERS } )
  742. def test_OmniCompleter_GetCompletions_FiletypeDisabled_SemanticTrigger(
  743. self, ycm ):
  744. def Omnifunc( findstart, base ):
  745. if findstart:
  746. return 5
  747. return [ 'a', 'b', 'cdef' ]
  748. current_buffer = VimBuffer( 'buffer',
  749. contents = [ 'test.' ],
  750. filetype = FILETYPE,
  751. omnifunc = Omnifunc )
  752. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
  753. ycm.SendCompletionRequest()
  754. assert_that(
  755. ycm.GetCompletionResponse(),
  756. has_entries( {
  757. 'completions': empty(),
  758. 'completion_start_column': 6
  759. } )
  760. )
  761. @YouCompleteMeInstance( {
  762. 'g:ycm_cache_omnifunc': 0,
  763. 'g:ycm_filetype_specific_completion_to_disable': { '*': 1 },
  764. 'g:ycm_semantic_triggers': TRIGGERS } )
  765. def test_OmniCompleter_GetCompletions_AllFiletypesDisabled_SemanticTrigger(
  766. self, ycm ):
  767. def Omnifunc( findstart, base ):
  768. if findstart:
  769. return 5
  770. return [ 'a', 'b', 'cdef' ]
  771. current_buffer = VimBuffer( 'buffer',
  772. contents = [ 'test.' ],
  773. filetype = FILETYPE,
  774. omnifunc = Omnifunc )
  775. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
  776. ycm.SendCompletionRequest()
  777. assert_that(
  778. ycm.GetCompletionResponse(),
  779. has_entries( {
  780. 'completions': empty(),
  781. 'completion_start_column': 6
  782. } )
  783. )
  784. @YouCompleteMeInstance( {
  785. 'g:ycm_cache_omnifunc': 0,
  786. 'g:ycm_filetype_specific_completion_to_disable': { FILETYPE: 1 },
  787. 'g:ycm_semantic_triggers': TRIGGERS } )
  788. def test_OmniCompleter_GetCompletions_FiletypeDisabled_ForceSemantic(
  789. self, ycm ):
  790. def Omnifunc( findstart, base ):
  791. if findstart:
  792. return 5
  793. return [ 'a', 'b', 'cdef' ]
  794. current_buffer = VimBuffer( 'buffer',
  795. contents = [ 'test.' ],
  796. filetype = FILETYPE,
  797. omnifunc = Omnifunc )
  798. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
  799. ycm.SendCompletionRequest( force_semantic = True )
  800. assert_that(
  801. ycm.GetCompletionResponse(),
  802. has_entries( {
  803. 'completions': [
  804. { 'word': 'a', 'equal': 1 },
  805. { 'word': 'b', 'equal': 1 },
  806. { 'word': 'cdef', 'equal': 1 }
  807. ],
  808. 'completion_start_column': 6
  809. } )
  810. )
  811. @YouCompleteMeInstance( {
  812. 'g:ycm_cache_omnifunc': 0,
  813. 'g:ycm_filetype_specific_completion_to_disable': { '*': 1 },
  814. 'g:ycm_semantic_triggers': TRIGGERS } )
  815. def test_OmniCompleter_GetCompletions_AllFiletypesDisabled_ForceSemantic(
  816. self, ycm ):
  817. def Omnifunc( findstart, base ):
  818. if findstart:
  819. return 5
  820. return [ 'a', 'b', 'cdef' ]
  821. current_buffer = VimBuffer( 'buffer',
  822. contents = [ 'test.' ],
  823. filetype = FILETYPE,
  824. omnifunc = Omnifunc )
  825. with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
  826. ycm.SendCompletionRequest( force_semantic = True )
  827. assert_that(
  828. ycm.GetCompletionResponse(),
  829. has_entries( {
  830. 'completions': [
  831. { 'word': 'a', 'equal': 1 },
  832. { 'word': 'b', 'equal': 1 },
  833. { 'word': 'cdef', 'equal': 1 }
  834. ],
  835. 'completion_start_column': 6
  836. } )
  837. )