142 lines
4.3 KiB
Python
142 lines
4.3 KiB
Python
# Copyright (C) 2016-2018 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
|
|
# Not installing aliases from python-future; it's unreliable and slow.
|
|
from builtins import * # noqa
|
|
|
|
from ycm.tests.test_utils import MockVimModule
|
|
MockVimModule()
|
|
|
|
import contextlib
|
|
import functools
|
|
import os
|
|
import requests
|
|
import time
|
|
import warnings
|
|
|
|
from ycm.client.base_request import BaseRequest
|
|
from ycm.tests import test_utils
|
|
from ycm.youcompleteme import YouCompleteMe
|
|
from ycmd.utils import CloseStandardStreams, WaitUntilProcessIsTerminated
|
|
|
|
# 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 = {
|
|
'g:ycm_server_python_interpreter': '',
|
|
'g:ycm_log_level': 'info',
|
|
'g:ycm_keep_logfiles': 0,
|
|
'g:ycm_extra_conf_vim_data': [],
|
|
'g:ycm_show_diagnostics_ui': 1,
|
|
'g:ycm_echo_current_diagnostic': 1,
|
|
'g:ycm_enable_diagnostic_signs': 1,
|
|
'g:ycm_enable_diagnostic_highlighting': 0,
|
|
'g:ycm_always_populate_location_list': 0,
|
|
}
|
|
|
|
|
|
def PathToTestFile( *args ):
|
|
dir_of_current_script = os.path.dirname( os.path.abspath( __file__ ) )
|
|
return os.path.join( dir_of_current_script, 'testdata', *args )
|
|
|
|
|
|
@contextlib.contextmanager
|
|
def UserOptions( options ):
|
|
old_vim_options = test_utils.VIM_OPTIONS.copy()
|
|
test_utils.VIM_OPTIONS.update( DEFAULT_CLIENT_OPTIONS )
|
|
test_utils.VIM_OPTIONS.update( options )
|
|
try:
|
|
yield
|
|
finally:
|
|
test_utils.VIM_OPTIONS = old_vim_options
|
|
|
|
|
|
def _IsReady():
|
|
return BaseRequest().GetDataFromHandler( 'ready' )
|
|
|
|
|
|
def WaitUntilReady( timeout = 5 ):
|
|
expiration = time.time() + timeout
|
|
while True:
|
|
try:
|
|
if time.time() > expiration:
|
|
raise RuntimeError( 'Waited for the server to be ready '
|
|
'for {0} seconds, aborting.'.format( timeout ) )
|
|
if _IsReady():
|
|
return
|
|
except requests.exceptions.ConnectionError:
|
|
pass
|
|
finally:
|
|
time.sleep( 0.1 )
|
|
|
|
|
|
def StopServer( ycm ):
|
|
try:
|
|
ycm.OnVimLeave()
|
|
WaitUntilProcessIsTerminated( ycm._server_popen )
|
|
CloseStandardStreams( ycm._server_popen )
|
|
except Exception:
|
|
pass
|
|
|
|
|
|
def setUpPackage():
|
|
# We treat warnings as errors in our tests because warnings raised inside Vim
|
|
# will interrupt user workflow with a traceback and we don't want that.
|
|
warnings.filterwarnings( 'error' )
|
|
# We ignore warnings from nose as we are not interested in them.
|
|
warnings.filterwarnings( 'ignore', module = 'nose' )
|
|
|
|
|
|
def tearDownPackage():
|
|
warnings.resetwarnings()
|
|
|
|
|
|
def YouCompleteMeInstance( custom_options = {} ):
|
|
"""Defines a decorator function for tests that passes a unique YouCompleteMe
|
|
instance as a parameter. This instance is initialized with the default options
|
|
`DEFAULT_CLIENT_OPTIONS`. Use the optional parameter |custom_options| to give
|
|
additional options and/or override the already existing ones.
|
|
|
|
Do NOT attach it to test generators but directly to the yielded tests.
|
|
|
|
Example usage:
|
|
|
|
from ycm.tests import YouCompleteMeInstance
|
|
|
|
@YouCompleteMeInstance( { 'log_level': 'debug',
|
|
'keep_logfiles': 1 } )
|
|
def Debug_test( ycm ):
|
|
...
|
|
"""
|
|
def Decorator( test ):
|
|
@functools.wraps( test )
|
|
def Wrapper( *args, **kwargs ):
|
|
with UserOptions( custom_options ):
|
|
ycm = YouCompleteMe()
|
|
WaitUntilReady()
|
|
ycm.CheckIfServerIsReady()
|
|
try:
|
|
test( ycm, *args, **kwargs )
|
|
finally:
|
|
StopServer( ycm )
|
|
return Wrapper
|
|
return Decorator
|