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