Add tests for omni completer GetCompletions
This commit is contained in:
parent
81db1c0b23
commit
e73426187d
@ -66,8 +66,7 @@ class OmniCompleter( Completer ):
|
||||
|
||||
def ComputeCandidates( self, request_data ):
|
||||
if self.ShouldUseCache():
|
||||
return super( OmniCompleter, self ).ComputeCandidates(
|
||||
request_data )
|
||||
return super( OmniCompleter, self ).ComputeCandidates( request_data )
|
||||
else:
|
||||
if self.ShouldUseNowInner( request_data ):
|
||||
return self.ComputeCandidatesInner( request_data )
|
||||
@ -81,6 +80,7 @@ class OmniCompleter( Completer ):
|
||||
try:
|
||||
return_value = int( vim.eval( self._omnifunc + '(1,"")' ) )
|
||||
if return_value < 0:
|
||||
# FIXME: Technically, if the return is -1 we should raise an error
|
||||
return []
|
||||
|
||||
omnifunc_call = [ self._omnifunc,
|
||||
@ -90,13 +90,13 @@ class OmniCompleter( Completer ):
|
||||
|
||||
items = vim.eval( ''.join( omnifunc_call ) )
|
||||
|
||||
if hasattr( items, '__getitem__' ) and 'words' in items:
|
||||
if isinstance( items, dict ) and 'words' in items:
|
||||
items = items[ 'words' ]
|
||||
|
||||
if not hasattr( items, '__iter__' ):
|
||||
raise TypeError( OMNIFUNC_NOT_LIST )
|
||||
|
||||
return [ utils.ToUnicode( i ) for i in items if bool( i ) ]
|
||||
return list( filter( bool, items ) )
|
||||
|
||||
except ( TypeError, ValueError, vim.error ) as error:
|
||||
vimsupport.PostVimMessage(
|
||||
@ -105,7 +105,7 @@ class OmniCompleter( Completer ):
|
||||
|
||||
|
||||
def OnFileReadyToParse( self, request_data ):
|
||||
self._omnifunc = vim.eval( '&omnifunc' )
|
||||
self._omnifunc = utils.ToUnicode( vim.eval( '&omnifunc' ) )
|
||||
|
||||
|
||||
def FilterAndSortCandidatesInner( self, candidates, sort_property, query ):
|
||||
|
@ -27,6 +27,10 @@ from mock import MagicMock
|
||||
from hamcrest import assert_that, equal_to
|
||||
import re
|
||||
import sys
|
||||
import nose
|
||||
import functools
|
||||
|
||||
from ycmd.utils import ToUnicode
|
||||
|
||||
|
||||
BUFNR_REGEX = re.compile( r"^bufnr\('(.+)', ([0-9]+)\)$" )
|
||||
@ -43,6 +47,18 @@ BWIPEOUT_REGEX = re.compile( r"^(?:silent! )bwipeout!? ([0-9]+)$" )
|
||||
# https://github.com/Valloric/YouCompleteMe/pull/1694
|
||||
VIM_MOCK = MagicMock()
|
||||
|
||||
# The default options which are only relevant to the client, not the server and
|
||||
# thus are not part of default_options.json, but are required for a working
|
||||
# YouCompleteMe or OmniCompleter object.
|
||||
DEFAULT_CLIENT_OPTIONS = {
|
||||
'server_log_level': 'info',
|
||||
'extra_conf_vim_data': [],
|
||||
'show_diagnostics_ui': 1,
|
||||
'enable_diagnostic_signs': 1,
|
||||
'enable_diagnostic_highlighting': 0,
|
||||
'always_populate_location_list': 0,
|
||||
}
|
||||
|
||||
|
||||
def MockGetBufferNumber( buffer_filename ):
|
||||
for buffer in VIM_MOCK.buffers:
|
||||
@ -126,7 +142,60 @@ def MockVimModule():
|
||||
|
||||
|
||||
class ExtendedMock( MagicMock ):
|
||||
"""An extension to the MagicMock class which adds the ability to check that a
|
||||
callable is called with a precise set of calls in a precise order.
|
||||
|
||||
Example Usage:
|
||||
from ycm.test_utils import ExtendedMock
|
||||
@patch( 'test.testing', new_callable = ExtendedMock, ... )
|
||||
def my_test( test_testing ):
|
||||
...
|
||||
"""
|
||||
|
||||
def assert_has_exact_calls( self, calls, any_order = False ):
|
||||
self.assert_has_calls( calls, any_order )
|
||||
assert_that( self.call_count, equal_to( len( calls ) ) )
|
||||
|
||||
|
||||
def ExpectedFailure( reason, *exception_matchers ):
|
||||
"""Defines a decorator to be attached to tests. This decorator
|
||||
marks the test as being known to fail, e.g. where documenting or exercising
|
||||
known incorrect behaviour.
|
||||
|
||||
The parameters are:
|
||||
- |reason| a textual description of the reason for the known issue. This
|
||||
is used for the skip reason
|
||||
- |exception_matchers| additional arguments are hamcrest matchers to apply
|
||||
to the exception thrown. If the matchers don't match, then the
|
||||
test is marked as error, with the original exception.
|
||||
|
||||
If the test fails (for the correct reason), then it is marked as skipped.
|
||||
If it fails for any other reason, it is marked as failed.
|
||||
If the test passes, then it is also marked as failed."""
|
||||
def decorator( test ):
|
||||
@functools.wraps( test )
|
||||
def Wrapper( *args, **kwargs ):
|
||||
try:
|
||||
test( *args, **kwargs )
|
||||
except Exception as test_exception:
|
||||
# Ensure that we failed for the right reason
|
||||
test_exception_message = ToUnicode( test_exception )
|
||||
try:
|
||||
for matcher in exception_matchers:
|
||||
assert_that( test_exception_message, matcher )
|
||||
except AssertionError:
|
||||
# Failed for the wrong reason!
|
||||
import traceback
|
||||
print( 'Test failed for the wrong reason: ' + traceback.format_exc() )
|
||||
# Real failure reason is the *original* exception, we're only trapping
|
||||
# and ignoring the exception that is expected.
|
||||
raise test_exception
|
||||
|
||||
# Failed for the right reason
|
||||
raise nose.SkipTest( reason )
|
||||
else:
|
||||
raise AssertionError( 'Test was expected to fail: {0}'.format(
|
||||
reason ) )
|
||||
return Wrapper
|
||||
|
||||
return decorator
|
||||
|
@ -23,7 +23,7 @@ from future import standard_library
|
||||
standard_library.install_aliases()
|
||||
from builtins import * # noqa
|
||||
|
||||
from ycm.test_utils import MockVimModule, ExtendedMock
|
||||
from ycm.test_utils import MockVimModule, ExtendedMock, DEFAULT_CLIENT_OPTIONS
|
||||
MockVimModule()
|
||||
|
||||
import contextlib
|
||||
@ -38,19 +38,6 @@ from mock import call, MagicMock, patch
|
||||
from nose.tools import eq_, ok_
|
||||
|
||||
|
||||
# The default options which are only relevant to the client, not the server and
|
||||
# thus are not part of default_options.json, but are required for a working
|
||||
# YouCompleteMe object.
|
||||
DEFAULT_CLIENT_OPTIONS = {
|
||||
'server_log_level': 'info',
|
||||
'extra_conf_vim_data': [],
|
||||
'show_diagnostics_ui': 1,
|
||||
'enable_diagnostic_signs': 1,
|
||||
'enable_diagnostic_highlighting': 0,
|
||||
'always_populate_location_list': 0,
|
||||
}
|
||||
|
||||
|
||||
def PostVimMessage_Call( message ):
|
||||
"""Return a mock.call object for a call to vimsupport.PostVimMesasge with the
|
||||
supplied message"""
|
||||
|
758
python/ycm/tests/omni_completer_test.py
Normal file
758
python/ycm/tests/omni_completer_test.py
Normal file
@ -0,0 +1,758 @@
|
||||
# encoding: utf-8
|
||||
#
|
||||
# Copyright (C) 2016 YouCompleteMe contributors
|
||||
#
|
||||
# This file is part of YouCompleteMe.
|
||||
#
|
||||
# YouCompleteMe is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# YouCompleteMe is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
from __future__ import print_function
|
||||
from __future__ import division
|
||||
from __future__ import absolute_import
|
||||
from future import standard_library
|
||||
standard_library.install_aliases()
|
||||
from builtins import * # noqa
|
||||
from future.utils import PY2
|
||||
|
||||
from mock import patch, call
|
||||
from nose.tools import eq_
|
||||
from hamcrest import contains_string
|
||||
|
||||
from ycm.test_utils import MockVimModule, ExtendedMock
|
||||
MockVimModule()
|
||||
|
||||
from ycm.test_utils import DEFAULT_CLIENT_OPTIONS, ExpectedFailure
|
||||
from ycm.omni_completer import OmniCompleter
|
||||
from ycm.youcompleteme import YouCompleteMe
|
||||
|
||||
from ycmd import user_options_store
|
||||
from ycmd.utils import ToBytes
|
||||
from ycmd.request_wrap import RequestWrap
|
||||
|
||||
|
||||
def ToBytesOnPY2( data ):
|
||||
# To test the omnifunc, etc. returning strings, which can be of different
|
||||
# types depending on python version, we use ToBytes on PY2 and just the native
|
||||
# str on python3. This roughly matches what happens between py2 and py3
|
||||
# versions within Vim
|
||||
if PY2:
|
||||
return ToBytes( data )
|
||||
|
||||
return data
|
||||
|
||||
|
||||
def BuildRequest( line_num, column_num, contents ):
|
||||
# Note: it would be nice to use ycmd.test_utils.BuildRequest directly here,
|
||||
# but we can't import ycmd.test_utils because that in turn imports ycm_core,
|
||||
# which would cause our "ycm_core not imported" test to fail.
|
||||
return {
|
||||
'line_num': line_num,
|
||||
'column_num': column_num,
|
||||
'filepath': '/test',
|
||||
'file_data': {
|
||||
'/test': {
|
||||
'contents': contents,
|
||||
'filetypes': [ 'java' ] # We need a filetype with a trigger, so we just
|
||||
# use java
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def BuildRequestWrap( line_num, column_num, contents ):
|
||||
return RequestWrap( BuildRequest( line_num, column_num, contents ) )
|
||||
|
||||
|
||||
def MakeUserOptions( custom_options = {} ):
|
||||
options = dict( user_options_store.DefaultOptions() )
|
||||
options.update( DEFAULT_CLIENT_OPTIONS )
|
||||
options.update( custom_options )
|
||||
return options
|
||||
|
||||
|
||||
class OmniCompleter_test( object ):
|
||||
|
||||
def setUp( self ):
|
||||
# We need a server instance for FilterAndSortCandidates
|
||||
self._server_state = YouCompleteMe( MakeUserOptions() )
|
||||
|
||||
|
||||
def tearDown( self ):
|
||||
self._server_state.OnVimLeave()
|
||||
|
||||
|
||||
def OmniCompleter_GetCompletions_Cache_List_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 1
|
||||
} ) )
|
||||
|
||||
contents = 'test.'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 6,
|
||||
contents = contents )
|
||||
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = [ ToBytesOnPY2( 'a' ),
|
||||
ToBytesOnPY2( 'b' ),
|
||||
ToBytesOnPY2( 'cdef' ) ]
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 6, omnifunc_result ] ) as vim_eval:
|
||||
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
call( "test_omnifunc(0,'')" ),
|
||||
] )
|
||||
|
||||
eq_( results, omnifunc_result )
|
||||
|
||||
|
||||
def OmniCompleter_GetCompletions_Cache_ListFilter_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 1
|
||||
} ) )
|
||||
|
||||
contents = 'test.t'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 7,
|
||||
contents = contents )
|
||||
|
||||
eq_( request_data[ 'query' ], 't' )
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = [ ToBytesOnPY2( 'a' ),
|
||||
ToBytesOnPY2( 'b' ),
|
||||
ToBytesOnPY2( 'cdef' ) ]
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 6, omnifunc_result ] ) as vim_eval:
|
||||
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
call( "test_omnifunc(0,'t')" ),
|
||||
] )
|
||||
|
||||
eq_( results, [] )
|
||||
|
||||
|
||||
def OmniCompleter_GetCompletions_NoCache_List_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 0
|
||||
} ) )
|
||||
|
||||
contents = 'test.'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 6,
|
||||
contents = contents )
|
||||
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = [ ToBytesOnPY2( 'a' ),
|
||||
ToBytesOnPY2( 'b' ),
|
||||
ToBytesOnPY2( 'cdef' ) ]
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 6, omnifunc_result ] ) as vim_eval:
|
||||
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
call( "test_omnifunc(0,'')" ),
|
||||
] )
|
||||
|
||||
eq_( results, omnifunc_result )
|
||||
|
||||
|
||||
def OmniCompleter_GetCompletions_NoCache_ListFilter_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 0
|
||||
} ) )
|
||||
|
||||
contents = 'test.t'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 7,
|
||||
contents = contents )
|
||||
|
||||
eq_( request_data[ 'query' ], 't' )
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = [ ToBytesOnPY2( 'a' ),
|
||||
ToBytesOnPY2( 'b' ),
|
||||
ToBytesOnPY2( 'cdef' ) ]
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 6, omnifunc_result ] ) as vim_eval:
|
||||
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
call( "test_omnifunc(0,'t')" ),
|
||||
] )
|
||||
|
||||
# actual result is that the results are not filtered, as we expect the
|
||||
# omniufunc or vim itself to do this filtering
|
||||
eq_( results, omnifunc_result )
|
||||
|
||||
|
||||
@ExpectedFailure( 'We ignore the result of the call to findstart and use our '
|
||||
'own interpretation of where the identifier should be',
|
||||
contains_string( "test_omnifunc(0,'t')" ) )
|
||||
def OmniCompleter_GetCompletsions_UseFindStart_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 1
|
||||
} ) )
|
||||
|
||||
contents = 'test.t'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 7,
|
||||
contents = contents )
|
||||
|
||||
eq_( request_data[ 'query' ], 't' )
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = [ ToBytesOnPY2( 'a' ),
|
||||
ToBytesOnPY2( 'b' ),
|
||||
ToBytesOnPY2( 'cdef' ) ]
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 1, omnifunc_result ] ) as vim_eval:
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
|
||||
# Fails here: actual result is that the findstart result (1) is ignored
|
||||
# and we use the 't' query as we normally would on the server side
|
||||
call( "test_omnifunc(0,'test.t')" ),
|
||||
] )
|
||||
|
||||
eq_( results, omnifunc_result )
|
||||
|
||||
|
||||
def OmniCompleter_GetCompletions_Cache_Object_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 1
|
||||
} ) )
|
||||
|
||||
contents = 'test.t'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 7,
|
||||
contents = contents )
|
||||
|
||||
eq_( request_data[ 'query' ], 't' )
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = {
|
||||
'words': [
|
||||
ToBytesOnPY2( 'a' ),
|
||||
ToBytesOnPY2( 'b' ),
|
||||
ToBytesOnPY2( 'CDtEF' )
|
||||
]
|
||||
}
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 6, omnifunc_result ] ) as vim_eval:
|
||||
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
call( "test_omnifunc(0,'t')" ),
|
||||
] )
|
||||
|
||||
eq_( results, [ ToBytesOnPY2( 'CDtEF' ) ] )
|
||||
|
||||
|
||||
def OmniCompleter_GetCompletions_Cache_ObjectList_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 1
|
||||
} ) )
|
||||
|
||||
contents = 'test.tt'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 8,
|
||||
contents = contents )
|
||||
|
||||
eq_( request_data[ 'query' ], 'tt' )
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = [
|
||||
{
|
||||
'word': ToBytesOnPY2( 'a' ),
|
||||
'abbr': ToBytesOnPY2( 'ABBR'),
|
||||
'menu': ToBytesOnPY2( 'MENU' ),
|
||||
'info': ToBytesOnPY2( 'INFO' ),
|
||||
'kind': ToBytesOnPY2( 'K' )
|
||||
},
|
||||
{
|
||||
'word': ToBytesOnPY2( 'test' ),
|
||||
'abbr': ToBytesOnPY2( 'ABBRTEST'),
|
||||
'menu': ToBytesOnPY2( 'MENUTEST' ),
|
||||
'info': ToBytesOnPY2( 'INFOTEST' ),
|
||||
'kind': ToBytesOnPY2( 'T' )
|
||||
}
|
||||
]
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 6, omnifunc_result ] ) as vim_eval:
|
||||
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
call( "test_omnifunc(0,'tt')" ),
|
||||
] )
|
||||
|
||||
eq_( results, [ omnifunc_result[ 1 ] ] )
|
||||
|
||||
|
||||
def OmniCompleter_GetCompletions_NoCache_ObjectList_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 0
|
||||
} ) )
|
||||
|
||||
contents = 'test.tt'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 8,
|
||||
contents = contents )
|
||||
|
||||
eq_( request_data[ 'query' ], 'tt' )
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = [
|
||||
{
|
||||
'word': ToBytesOnPY2( 'a' ),
|
||||
'abbr': ToBytesOnPY2( 'ABBR'),
|
||||
'menu': ToBytesOnPY2( 'MENU' ),
|
||||
'info': ToBytesOnPY2( 'INFO' ),
|
||||
'kind': ToBytesOnPY2( 'K' )
|
||||
},
|
||||
{
|
||||
'word': ToBytesOnPY2( 'test' ),
|
||||
'abbr': ToBytesOnPY2( 'ABBRTEST'),
|
||||
'menu': ToBytesOnPY2( 'MENUTEST' ),
|
||||
'info': ToBytesOnPY2( 'INFOTEST' ),
|
||||
'kind': ToBytesOnPY2( 'T' )
|
||||
}
|
||||
]
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 6, omnifunc_result ] ) as vim_eval:
|
||||
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
call( "test_omnifunc(0,'tt')" ),
|
||||
] )
|
||||
|
||||
# We don't filter the result - we expect the omnifunc to do that
|
||||
# based on the query we supplied (Note: that means no fuzzy matching!)
|
||||
eq_( results, omnifunc_result )
|
||||
|
||||
|
||||
def OmniCompleter_GetCompletions_Cache_ObjectListObject_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 1
|
||||
} ) )
|
||||
|
||||
contents = 'test.tt'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 8,
|
||||
contents = contents )
|
||||
|
||||
eq_( request_data[ 'query' ], 'tt' )
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = {
|
||||
'words': [
|
||||
{
|
||||
'word': ToBytesOnPY2( 'a' ),
|
||||
'abbr': ToBytesOnPY2( 'ABBR'),
|
||||
'menu': ToBytesOnPY2( 'MENU' ),
|
||||
'info': ToBytesOnPY2( 'INFO' ),
|
||||
'kind': ToBytesOnPY2( 'K' )
|
||||
},
|
||||
{
|
||||
'word': ToBytesOnPY2( 'test' ),
|
||||
'abbr': ToBytesOnPY2( 'ABBRTEST'),
|
||||
'menu': ToBytesOnPY2( 'MENUTEST' ),
|
||||
'info': ToBytesOnPY2( 'INFOTEST' ),
|
||||
'kind': ToBytesOnPY2( 'T' )
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 6, omnifunc_result ] ) as vim_eval:
|
||||
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
call( "test_omnifunc(0,'tt')" ),
|
||||
] )
|
||||
|
||||
eq_( results, [ omnifunc_result[ 'words' ][ 1 ] ] )
|
||||
|
||||
|
||||
def OmniCompleter_GetCompletions_NoCache_ObjectListObject_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 0
|
||||
} ) )
|
||||
|
||||
contents = 'test.tt'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 8,
|
||||
contents = contents )
|
||||
|
||||
eq_( request_data[ 'query' ], 'tt' )
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = {
|
||||
'words': [
|
||||
{
|
||||
'word': ToBytesOnPY2( 'a' ),
|
||||
'abbr': ToBytesOnPY2( 'ABBR'),
|
||||
'menu': ToBytesOnPY2( 'MENU' ),
|
||||
'info': ToBytesOnPY2( 'INFO' ),
|
||||
'kind': ToBytesOnPY2( 'K' )
|
||||
},
|
||||
{
|
||||
'word': ToBytesOnPY2( 'test' ),
|
||||
'abbr': ToBytesOnPY2( 'ABBRTEST'),
|
||||
'menu': ToBytesOnPY2( 'MENUTEST' ),
|
||||
'info': ToBytesOnPY2( 'INFOTEST' ),
|
||||
'kind': ToBytesOnPY2( 'T' )
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 6, omnifunc_result ] ) as vim_eval:
|
||||
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
call( "test_omnifunc(0,'tt')" ),
|
||||
] )
|
||||
|
||||
# No FilterAndSortCandidates for cache_omnifunc=0 (we expect the omnifunc
|
||||
# to do the filtering?)
|
||||
eq_( results, omnifunc_result[ 'words' ] )
|
||||
|
||||
|
||||
def OmniCompleter_GetCompletions_Cache_List_Unicode_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 1
|
||||
} ) )
|
||||
|
||||
contents = '†åsty_π.'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 13,
|
||||
contents = contents )
|
||||
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = [ ToBytesOnPY2( '†est' ),
|
||||
ToBytesOnPY2( 'å_unicode_identifier' ),
|
||||
ToBytesOnPY2( 'πππππππ yummy πie' ) ]
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 6, omnifunc_result ] ) as vim_eval:
|
||||
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
call( "test_omnifunc(0,'')" ),
|
||||
] )
|
||||
|
||||
eq_( results, omnifunc_result )
|
||||
|
||||
|
||||
def OmniCompleter_GetCompletions_NoCache_List_Unicode_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 0
|
||||
} ) )
|
||||
|
||||
contents = '†åsty_π.'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 13,
|
||||
contents = contents )
|
||||
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = [ ToBytesOnPY2( '†est' ),
|
||||
ToBytesOnPY2( 'å_unicode_identifier' ),
|
||||
ToBytesOnPY2( 'πππππππ yummy πie' ) ]
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 6, omnifunc_result ] ) as vim_eval:
|
||||
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
call( "test_omnifunc(0,'')" ),
|
||||
] )
|
||||
|
||||
eq_( results, omnifunc_result )
|
||||
|
||||
|
||||
@ExpectedFailure( 'Filtering on unicode is not supported by the server' )
|
||||
def OmniCompleter_GetCompletions_Cache_List_Filter_Unicode_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 1
|
||||
} ) )
|
||||
|
||||
contents = '†åsty_π.ππ'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 17,
|
||||
contents = contents )
|
||||
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = [ ToBytesOnPY2( '†est' ),
|
||||
ToBytesOnPY2( 'å_unicode_identifier' ),
|
||||
ToBytesOnPY2( 'πππππππ yummy πie' ) ]
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 6, omnifunc_result ] ) as vim_eval:
|
||||
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
call( "test_omnifunc(0,'ππ')" ),
|
||||
] )
|
||||
|
||||
# Fails here: Filtering on unicode is not supported
|
||||
eq_( results, [ omnifunc_result[ 2 ] ] )
|
||||
|
||||
|
||||
def OmniCompleter_GetCompletions_NoCache_List_Filter_Unicode_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 0
|
||||
} ) )
|
||||
|
||||
contents = '†åsty_π.ππ'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 17,
|
||||
contents = contents )
|
||||
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = [ ToBytesOnPY2( 'πππππππ yummy πie' ) ]
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 6, omnifunc_result ] ) as vim_eval:
|
||||
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
call( "test_omnifunc(0,'ππ')" ),
|
||||
] )
|
||||
|
||||
eq_( results, omnifunc_result )
|
||||
|
||||
|
||||
@ExpectedFailure( 'Filtering on unicode is not supported by the server' )
|
||||
def OmniCompleter_GetCompletions_Cache_ObjectList_Unicode_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 1
|
||||
} ) )
|
||||
|
||||
contents = '†åsty_π.ππ'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 17,
|
||||
contents = contents )
|
||||
|
||||
|
||||
eq_( request_data[ 'query' ], 'ππ' )
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = [
|
||||
{
|
||||
'word': ToBytesOnPY2( 'ålpha∫et' ),
|
||||
'abbr': ToBytesOnPY2( 'å∫∫®'),
|
||||
'menu': ToBytesOnPY2( 'µ´~¨á' ),
|
||||
'info': ToBytesOnPY2( '^~fo' ),
|
||||
'kind': ToBytesOnPY2( '˚' )
|
||||
},
|
||||
{
|
||||
'word': ToBytesOnPY2( 'π†´ß†π' ),
|
||||
'abbr': ToBytesOnPY2( 'ÅııÂʉÍÊ'),
|
||||
'menu': ToBytesOnPY2( '˜‰ˆËʉÍÊ' ),
|
||||
'info': ToBytesOnPY2( 'ȈÏØʉÍÊ' ),
|
||||
'kind': ToBytesOnPY2( 'Ê' )
|
||||
}
|
||||
]
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 6, omnifunc_result ] ) as vim_eval:
|
||||
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
call( "test_omnifunc(0,'ππ')" ),
|
||||
] )
|
||||
|
||||
# Fails here: Filtering on unicode is not supported
|
||||
eq_( results, [ omnifunc_result[ 1 ] ] )
|
||||
|
||||
|
||||
def OmniCompleter_GetCompletions_Cache_ObjectListObject_Unicode_test( self ):
|
||||
omni_completer = OmniCompleter( MakeUserOptions( {
|
||||
'cache_omnifunc': 1
|
||||
} ) )
|
||||
|
||||
contents = '†åsty_π.t'
|
||||
request_data = BuildRequestWrap( line_num = 1,
|
||||
column_num = 14,
|
||||
contents = contents )
|
||||
|
||||
|
||||
eq_( request_data[ 'query' ], 't' )
|
||||
|
||||
# Make sure there is an omnifunc set up.
|
||||
with patch( 'vim.eval', return_value = ToBytesOnPY2( 'test_omnifunc' ) ):
|
||||
omni_completer.OnFileReadyToParse( request_data )
|
||||
|
||||
omnifunc_result = {
|
||||
'words': [
|
||||
{
|
||||
'word': ToBytesOnPY2( 'ålpha∫et' ),
|
||||
'abbr': ToBytesOnPY2( 'å∫∫®'),
|
||||
'menu': ToBytesOnPY2( 'µ´~¨á' ),
|
||||
'info': ToBytesOnPY2( '^~fo' ),
|
||||
'kind': ToBytesOnPY2( '˚' )
|
||||
},
|
||||
{
|
||||
'word': ToBytesOnPY2( 'π†´ß†π' ),
|
||||
'abbr': ToBytesOnPY2( 'ÅııÂʉÍÊ'),
|
||||
'menu': ToBytesOnPY2( '˜‰ˆËʉÍÊ' ),
|
||||
'info': ToBytesOnPY2( 'ȈÏØʉÍÊ' ),
|
||||
'kind': ToBytesOnPY2( 'Ê' )
|
||||
},
|
||||
{
|
||||
'word': ToBytesOnPY2( 'test' ),
|
||||
'abbr': ToBytesOnPY2( 'ÅııÂʉÍÊ'),
|
||||
'menu': ToBytesOnPY2( '˜‰ˆËʉÍÊ' ),
|
||||
'info': ToBytesOnPY2( 'ȈÏØʉÍÊ' ),
|
||||
'kind': ToBytesOnPY2( 'Ê' )
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
# And get the completions
|
||||
with patch( 'vim.eval',
|
||||
new_callable = ExtendedMock,
|
||||
side_effect = [ 6, omnifunc_result ] ) as vim_eval:
|
||||
|
||||
results = omni_completer.ComputeCandidates( request_data )
|
||||
|
||||
vim_eval.assert_has_exact_calls( [
|
||||
call( 'test_omnifunc(1,"")' ),
|
||||
call( "test_omnifunc(0,'t')" ),
|
||||
] )
|
||||
|
||||
# Note: the filtered results are all unicode objects (not bytes) because
|
||||
# they are passed through the FilterAndSortCandidates machinery
|
||||
# (via the server)
|
||||
eq_( results, [ {
|
||||
'word': 'test',
|
||||
'abbr': 'ÅııÂʉÍÊ',
|
||||
'menu': '˜‰ˆËʉÍÊ',
|
||||
'info': 'ȈÏØʉÍÊ',
|
||||
'kind': 'Ê'
|
||||
} ] )
|
@ -28,13 +28,12 @@ from builtins import * # noqa
|
||||
from ycm.test_utils import MockVimModule
|
||||
MockVimModule()
|
||||
|
||||
from ycmd.utils import ToBytes
|
||||
|
||||
import contextlib
|
||||
from hamcrest import assert_that, empty
|
||||
from mock import MagicMock, DEFAULT, patch
|
||||
from nose.tools import eq_, ok_
|
||||
|
||||
from ycmd.utils import ToBytes
|
||||
from ycm import vimsupport
|
||||
from ycm.youcompleteme import YouCompleteMe
|
||||
|
||||
|
@ -72,10 +72,8 @@ def NoseTests( extra_args ):
|
||||
|
||||
def Main():
|
||||
( parsed_args, extra_args ) = ParseArguments()
|
||||
|
||||
if not parsed_args.no_flake8:
|
||||
RunFlake8()
|
||||
|
||||
BuildYcmdLibs( parsed_args )
|
||||
NoseTests( extra_args )
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user