Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[READY] Implement shutdown handler #2245

Merged
merged 3 commits into from Jul 23, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
54 changes: 54 additions & 0 deletions python/ycm/client/shutdown_request.py
@@ -0,0 +1,54 @@
# 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 requests.exceptions import ReadTimeout

from ycm.client.base_request import BaseRequest

TIMEOUT_SECONDS = 0.1


class ShutdownRequest( BaseRequest ):
def __init__( self ):
super( BaseRequest, self ).__init__()


def Start( self ):
try:
self.PostDataToHandler( {},
'shutdown',
TIMEOUT_SECONDS )
except ReadTimeout:
pass


def Response( self ):
return self._response


def SendShutdownRequest():
request = ShutdownRequest()
# This is a blocking call.
request.Start()
12 changes: 0 additions & 12 deletions python/ycm/test_utils.py
Expand Up @@ -47,18 +47,6 @@
# 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:
Expand Down
111 changes: 48 additions & 63 deletions python/ycm/tests/event_notification_test.py
Expand Up @@ -23,14 +23,13 @@
standard_library.install_aliases()
from builtins import * # noqa

from ycm.test_utils import MockVimModule, ExtendedMock, DEFAULT_CLIENT_OPTIONS
from ycm.test_utils import MockVimModule, ExtendedMock
MockVimModule()

import contextlib
import os

from ycm.youcompleteme import YouCompleteMe
from ycmd import user_options_store
from ycm.tests.server_test import Server_test
from ycmd.responses import ( BuildDiagnosticData, Diagnostic, Location, Range,
UnknownExtraConf, ServerError )

Expand Down Expand Up @@ -153,21 +152,7 @@ def MockEventNotification( response_method, native_filetype_completer = True ):
yield


class EventNotification_test( object ):

def setUp( self ):
options = dict( user_options_store.DefaultOptions() )
options.update( DEFAULT_CLIENT_OPTIONS )
user_options_store.SetAll( options )

self.server_state = YouCompleteMe( user_options_store.GetAll() )
pass


def tearDown( self ):
if self.server_state:
self.server_state.OnVimLeave()

class EventNotification_test( Server_test ):

@patch( 'vim.command', new_callable = ExtendedMock )
def FileReadyToParse_NonDiagnostic_Error_test( self, vim_command ):
Expand All @@ -181,25 +166,25 @@ def ErrorResponse( *args ):

with MockArbitraryBuffer( 'javascript' ):
with MockEventNotification( ErrorResponse ):
self.server_state.OnFileReadyToParse()
assert self.server_state.FileParseRequestReady()
self.server_state.HandleFileParseRequest()
self._server_state.OnFileReadyToParse()
assert self._server_state.FileParseRequestReady()
self._server_state.HandleFileParseRequest()

# The first call raises a warning
vim_command.assert_has_exact_calls( [
PostMultiLineNotice_Call( ERROR_TEXT ),
] )

# Subsequent calls don't re-raise the warning
self.server_state.HandleFileParseRequest()
self._server_state.HandleFileParseRequest()
vim_command.assert_has_exact_calls( [
PostMultiLineNotice_Call( ERROR_TEXT ),
] )

# But it does if a subsequent event raises again
self.server_state.OnFileReadyToParse()
assert self.server_state.FileParseRequestReady()
self.server_state.HandleFileParseRequest()
self._server_state.OnFileReadyToParse()
assert self._server_state.FileParseRequestReady()
self._server_state.HandleFileParseRequest()
vim_command.assert_has_exact_calls( [
PostMultiLineNotice_Call( ERROR_TEXT ),
PostMultiLineNotice_Call( ERROR_TEXT ),
Expand All @@ -210,8 +195,8 @@ def ErrorResponse( *args ):
def FileReadyToParse_NonDiagnostic_Error_NonNative_test( self, vim_command ):
with MockArbitraryBuffer( 'javascript' ):
with MockEventNotification( None, False ):
self.server_state.OnFileReadyToParse()
self.server_state.HandleFileParseRequest()
self._server_state.OnFileReadyToParse()
self._server_state.HandleFileParseRequest()
vim_command.assert_not_called()


Expand Down Expand Up @@ -243,9 +228,9 @@ def UnknownExtraConfResponse( *args ):
with patch( 'ycm.vimsupport.PresentDialog',
return_value = 0,
new_callable = ExtendedMock ) as present_dialog:
self.server_state.OnFileReadyToParse()
assert self.server_state.FileParseRequestReady()
self.server_state.HandleFileParseRequest()
self._server_state.OnFileReadyToParse()
assert self._server_state.FileParseRequestReady()
self._server_state.HandleFileParseRequest()

present_dialog.assert_has_exact_calls( [
PresentDialog_Confirm_Call( MESSAGE ),
Expand All @@ -255,7 +240,7 @@ def UnknownExtraConfResponse( *args ):
] )

# Subsequent calls don't re-raise the warning
self.server_state.HandleFileParseRequest()
self._server_state.HandleFileParseRequest()

present_dialog.assert_has_exact_calls( [
PresentDialog_Confirm_Call( MESSAGE )
Expand All @@ -265,9 +250,9 @@ def UnknownExtraConfResponse( *args ):
] )

# But it does if a subsequent event raises again
self.server_state.OnFileReadyToParse()
assert self.server_state.FileParseRequestReady()
self.server_state.HandleFileParseRequest()
self._server_state.OnFileReadyToParse()
assert self._server_state.FileParseRequestReady()
self._server_state.HandleFileParseRequest()

present_dialog.assert_has_exact_calls( [
PresentDialog_Confirm_Call( MESSAGE ),
Expand All @@ -282,9 +267,9 @@ def UnknownExtraConfResponse( *args ):
with patch( 'ycm.vimsupport.PresentDialog',
return_value = 1,
new_callable = ExtendedMock ) as present_dialog:
self.server_state.OnFileReadyToParse()
assert self.server_state.FileParseRequestReady()
self.server_state.HandleFileParseRequest()
self._server_state.OnFileReadyToParse()
assert self._server_state.FileParseRequestReady()
self._server_state.HandleFileParseRequest()

present_dialog.assert_has_exact_calls( [
PresentDialog_Confirm_Call( MESSAGE ),
Expand All @@ -294,7 +279,7 @@ def UnknownExtraConfResponse( *args ):
] )

# Subsequent calls don't re-raise the warning
self.server_state.HandleFileParseRequest()
self._server_state.HandleFileParseRequest()

present_dialog.assert_has_exact_calls( [
PresentDialog_Confirm_Call( MESSAGE )
Expand All @@ -304,9 +289,9 @@ def UnknownExtraConfResponse( *args ):
] )

# But it does if a subsequent event raises again
self.server_state.OnFileReadyToParse()
assert self.server_state.FileParseRequestReady()
self.server_state.HandleFileParseRequest()
self._server_state.OnFileReadyToParse()
assert self._server_state.FileParseRequestReady()
self._server_state.HandleFileParseRequest()

present_dialog.assert_has_exact_calls( [
PresentDialog_Confirm_Call( MESSAGE ),
Expand Down Expand Up @@ -337,23 +322,23 @@ def DiagnosticResponse( *args ):

with MockArbitraryBuffer( 'cpp' ):
with MockEventNotification( DiagnosticResponse ):
self.server_state.OnFileReadyToParse()
ok_( self.server_state.FileParseRequestReady() )
self.server_state.HandleFileParseRequest()
self._server_state.OnFileReadyToParse()
ok_( self._server_state.FileParseRequestReady() )
self._server_state.HandleFileParseRequest()
vim_command.assert_has_calls( [
PlaceSign_Call( 1, 1, 0, True )
] )
eq_( self.server_state.GetErrorCount(), 1 )
eq_( self.server_state.GetWarningCount(), 0 )
eq_( self._server_state.GetErrorCount(), 1 )
eq_( self._server_state.GetWarningCount(), 0 )

# Consequent calls to HandleFileParseRequest shouldn't mess with
# existing diagnostics, when there is no new parse request.
vim_command.reset_mock()
ok_( not self.server_state.FileParseRequestReady() )
self.server_state.HandleFileParseRequest()
ok_( not self._server_state.FileParseRequestReady() )
self._server_state.HandleFileParseRequest()
vim_command.assert_not_called()
eq_( self.server_state.GetErrorCount(), 1 )
eq_( self.server_state.GetWarningCount(), 0 )
eq_( self._server_state.GetErrorCount(), 1 )
eq_( self._server_state.GetWarningCount(), 0 )


@patch( 'vim.command' )
Expand All @@ -370,24 +355,24 @@ def DiagnosticResponse( *args ):

with MockArbitraryBuffer( 'cpp' ):
with MockEventNotification( DiagnosticResponse ):
self.server_state.OnFileReadyToParse()
ok_( self.server_state.FileParseRequestReady() )
self.server_state.HandleFileParseRequest()
self._server_state.OnFileReadyToParse()
ok_( self._server_state.FileParseRequestReady() )
self._server_state.HandleFileParseRequest()
vim_command.assert_has_calls( [
PlaceSign_Call( 2, 2, 0, False ),
UnplaceSign_Call( 1, 0 )
] )
eq_( self.server_state.GetErrorCount(), 0 )
eq_( self.server_state.GetWarningCount(), 1 )
eq_( self._server_state.GetErrorCount(), 0 )
eq_( self._server_state.GetWarningCount(), 1 )

# Consequent calls to HandleFileParseRequest shouldn't mess with
# existing diagnostics, when there is no new parse request.
vim_command.reset_mock()
ok_( not self.server_state.FileParseRequestReady() )
self.server_state.HandleFileParseRequest()
ok_( not self._server_state.FileParseRequestReady() )
self._server_state.HandleFileParseRequest()
vim_command.assert_not_called()
eq_( self.server_state.GetErrorCount(), 0 )
eq_( self.server_state.GetWarningCount(), 1 )
eq_( self._server_state.GetErrorCount(), 0 )
eq_( self._server_state.GetWarningCount(), 1 )


@patch( 'vim.command' )
Expand All @@ -397,10 +382,10 @@ def _Check_FileReadyToParse_Diagnostic_Clean( self, vim_command ):
# Should be called after _Check_FileReadyToParse_Diagnostic_Warning
with MockArbitraryBuffer( 'cpp' ):
with MockEventNotification( MagicMock( return_value = [] ) ):
self.server_state.OnFileReadyToParse()
self.server_state.HandleFileParseRequest()
self._server_state.OnFileReadyToParse()
self._server_state.HandleFileParseRequest()
vim_command.assert_has_calls( [
UnplaceSign_Call( 2, 0 )
] )
eq_( self.server_state.GetErrorCount(), 0 )
eq_( self.server_state.GetWarningCount(), 0 )
eq_( self._server_state.GetErrorCount(), 0 )
eq_( self._server_state.GetWarningCount(), 0 )
23 changes: 3 additions & 20 deletions python/ycm/tests/omni_completer_test.py
Expand Up @@ -33,11 +33,10 @@
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 ycm.test_utils import ExpectedFailure
from ycm.tests.server_test import MakeUserOptions, Server_test

from ycmd import user_options_store
from ycmd.utils import ToBytes
from ycmd.request_wrap import RequestWrap

Expand Down Expand Up @@ -75,23 +74,7 @@ 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()

class OmniCompleter_test( Server_test ):

def OmniCompleter_GetCompletions_Cache_List_test( self ):
omni_completer = OmniCompleter( MakeUserOptions( {
Expand Down