Add tests for Vim file and buffer operations
Refactor Vim mocking.
This commit is contained in:
parent
59b91817a0
commit
f23cbae2a8
@ -18,18 +18,23 @@
|
|||||||
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
# along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
from mock import MagicMock
|
from mock import MagicMock
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
BUFNR_REGEX = re.compile( r"bufnr\('(.+)', ([0-9]+)\)" )
|
||||||
|
|
||||||
# One-and only instance of mocked Vim object. The first 'import vim' that is
|
# One-and only instance of mocked Vim object. The first 'import vim' that is
|
||||||
# executed binds the vim module to the instance of MagicMock that is created,
|
# executed binds the vim module to the instance of MagicMock that is created,
|
||||||
# and subsquent assignments to sys.modules[ 'vim' ] don't retrospectively update
|
# and subsquent assignments to sys.modules[ 'vim' ] don't retrospectively
|
||||||
# them. The result is that while running the tests, we must assign only one
|
# update them. The result is that while running the tests, we must assign only
|
||||||
# instance of MagicMock to sys.modules[ 'vim' ] and always return it.
|
# one instance of MagicMock to sys.modules[ 'vim' ] and always return it.
|
||||||
#
|
#
|
||||||
# More explanation is available:
|
# More explanation is available:
|
||||||
# https://github.com/Valloric/YouCompleteMe/pull/1694
|
# https://github.com/Valloric/YouCompleteMe/pull/1694
|
||||||
VIM_MOCK = MagicMock()
|
VIM_MOCK = MagicMock()
|
||||||
|
|
||||||
|
|
||||||
def MockVimModule():
|
def MockVimModule():
|
||||||
"""The 'vim' module is something that is only present when running inside the
|
"""The 'vim' module is something that is only present when running inside the
|
||||||
Vim Python interpreter, so we replace it with a MagicMock for tests. If you
|
Vim Python interpreter, so we replace it with a MagicMock for tests. If you
|
||||||
@ -55,8 +60,24 @@ def MockVimModule():
|
|||||||
def VimEval( value ):
|
def VimEval( value ):
|
||||||
if value == "g:ycm_min_num_of_chars_for_completion":
|
if value == "g:ycm_min_num_of_chars_for_completion":
|
||||||
return 0
|
return 0
|
||||||
|
if value == "g:ycm_path_to_python_interpreter":
|
||||||
return ''
|
return ''
|
||||||
|
if value == "tempname()":
|
||||||
|
return '_TEMP_FILE_'
|
||||||
|
if value == "&previewheight":
|
||||||
|
# Default value from Vim
|
||||||
|
return 12
|
||||||
|
match = BUFNR_REGEX.search( value )
|
||||||
|
if match:
|
||||||
|
filename = match.group( 1 )
|
||||||
|
buffers = VIM_MOCK.buffers
|
||||||
|
if filename in buffers and buffers[ filename ]:
|
||||||
|
return buffers[ filename ].pop( 0 )
|
||||||
|
return -1
|
||||||
|
|
||||||
|
raise ValueError( 'Unexpected evaluation: ' + value )
|
||||||
|
|
||||||
|
VIM_MOCK.buffers = {}
|
||||||
VIM_MOCK.eval = MagicMock( side_effect = VimEval )
|
VIM_MOCK.eval = MagicMock( side_effect = VimEval )
|
||||||
sys.modules[ 'vim' ] = VIM_MOCK
|
sys.modules[ 'vim' ] = VIM_MOCK
|
||||||
|
|
||||||
|
@ -22,7 +22,9 @@ MockVimModule()
|
|||||||
|
|
||||||
from ycm import vimsupport
|
from ycm import vimsupport
|
||||||
from nose.tools import eq_
|
from nose.tools import eq_
|
||||||
|
from hamcrest import assert_that, calling, raises, none
|
||||||
from mock import MagicMock, call, patch
|
from mock import MagicMock, call, patch
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
def ReplaceChunk_SingleLine_Repl_1_test():
|
def ReplaceChunk_SingleLine_Repl_1_test():
|
||||||
@ -582,17 +584,9 @@ def _BuildChunk( start_line, start_column, end_line, end_column,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def _Mock_tempname( arg ):
|
|
||||||
if arg == 'tempname()':
|
|
||||||
return '_TEMP_FILE_'
|
|
||||||
|
|
||||||
raise ValueError( 'Unexpected evaluation: ' + arg )
|
|
||||||
|
|
||||||
|
|
||||||
@patch( 'vim.eval', side_effect=_Mock_tempname )
|
|
||||||
@patch( 'vim.command' )
|
@patch( 'vim.command' )
|
||||||
@patch( 'vim.current' )
|
@patch( 'vim.current' )
|
||||||
def WriteToPreviewWindow_test( vim_current, vim_command, vim_eval ):
|
def WriteToPreviewWindow_test( vim_current, vim_command ):
|
||||||
vim_current.window.options.__getitem__ = MagicMock( return_value = True )
|
vim_current.window.options.__getitem__ = MagicMock( return_value = True )
|
||||||
|
|
||||||
vimsupport.WriteToPreviewWindow( "test" )
|
vimsupport.WriteToPreviewWindow( "test" )
|
||||||
@ -615,9 +609,8 @@ def WriteToPreviewWindow_test( vim_current, vim_command, vim_eval ):
|
|||||||
], any_order = True )
|
], any_order = True )
|
||||||
|
|
||||||
|
|
||||||
@patch( 'vim.eval', side_effect=_Mock_tempname )
|
|
||||||
@patch( 'vim.current' )
|
@patch( 'vim.current' )
|
||||||
def WriteToPreviewWindow_MultiLine_test( vim_current, vim_eval ):
|
def WriteToPreviewWindow_MultiLine_test( vim_current ):
|
||||||
vim_current.window.options.__getitem__ = MagicMock( return_value = True )
|
vim_current.window.options.__getitem__ = MagicMock( return_value = True )
|
||||||
vimsupport.WriteToPreviewWindow( "test\ntest2" )
|
vimsupport.WriteToPreviewWindow( "test\ntest2" )
|
||||||
|
|
||||||
@ -625,10 +618,9 @@ def WriteToPreviewWindow_MultiLine_test( vim_current, vim_eval ):
|
|||||||
slice( None, None, None ), [ 'test', 'test2' ] )
|
slice( None, None, None ), [ 'test', 'test2' ] )
|
||||||
|
|
||||||
|
|
||||||
@patch( 'vim.eval', side_effect=_Mock_tempname )
|
|
||||||
@patch( 'vim.command' )
|
@patch( 'vim.command' )
|
||||||
@patch( 'vim.current' )
|
@patch( 'vim.current' )
|
||||||
def WriteToPreviewWindow_JumpFail_test( vim_current, vim_command, vim_eval ):
|
def WriteToPreviewWindow_JumpFail_test( vim_current, vim_command ):
|
||||||
vim_current.window.options.__getitem__ = MagicMock( return_value = False )
|
vim_current.window.options.__getitem__ = MagicMock( return_value = False )
|
||||||
|
|
||||||
vimsupport.WriteToPreviewWindow( "test" )
|
vimsupport.WriteToPreviewWindow( "test" )
|
||||||
@ -644,12 +636,9 @@ def WriteToPreviewWindow_JumpFail_test( vim_current, vim_command, vim_eval ):
|
|||||||
vim_current.buffer.options.__setitem__.assert_not_called()
|
vim_current.buffer.options.__setitem__.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
@patch( 'vim.eval', side_effect=_Mock_tempname )
|
|
||||||
@patch( 'vim.command' )
|
@patch( 'vim.command' )
|
||||||
@patch( 'vim.current' )
|
@patch( 'vim.current' )
|
||||||
def WriteToPreviewWindow_JumpFail_MultiLine_test( vim_current,
|
def WriteToPreviewWindow_JumpFail_MultiLine_test( vim_current, vim_command ):
|
||||||
vim_command,
|
|
||||||
vim_eval ):
|
|
||||||
|
|
||||||
vim_current.window.options.__getitem__ = MagicMock( return_value = False )
|
vim_current.window.options.__getitem__ = MagicMock( return_value = False )
|
||||||
|
|
||||||
@ -665,3 +654,75 @@ def WriteToPreviewWindow_JumpFail_MultiLine_test( vim_current,
|
|||||||
|
|
||||||
vim_current.buffer.__setitem__.assert_not_called()
|
vim_current.buffer.__setitem__.assert_not_called()
|
||||||
vim_current.buffer.options.__setitem__.assert_not_called()
|
vim_current.buffer.options.__setitem__.assert_not_called()
|
||||||
|
|
||||||
|
|
||||||
|
def CheckFilename_test():
|
||||||
|
assert_that(
|
||||||
|
calling( vimsupport.CheckFilename ).with_args( None ),
|
||||||
|
raises( RuntimeError, "'None' is not a valid filename" )
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_that(
|
||||||
|
calling( vimsupport.CheckFilename ).with_args( 'nonexistent_file' ),
|
||||||
|
raises( RuntimeError,
|
||||||
|
"filename 'nonexistent_file' cannot be opened. "
|
||||||
|
"\[Errno 2\] No such file or directory: 'nonexistent_file'" )
|
||||||
|
)
|
||||||
|
|
||||||
|
assert_that( vimsupport.CheckFilename( __file__ ), none() )
|
||||||
|
|
||||||
|
|
||||||
|
def BufferExistsForFilename_test():
|
||||||
|
buffers = {
|
||||||
|
os.path.realpath( 'some_filename' ): [ 1 ],
|
||||||
|
}
|
||||||
|
|
||||||
|
with patch.dict( 'vim.buffers', buffers ):
|
||||||
|
eq_( vimsupport.BufferExistsForFilename( 'some_filename' ), True )
|
||||||
|
eq_( vimsupport.BufferExistsForFilename( 'another_filename' ), False )
|
||||||
|
|
||||||
|
|
||||||
|
@patch( 'vim.command' )
|
||||||
|
def CloseBuffersForFilename_test( vim_command ):
|
||||||
|
buffers = {
|
||||||
|
os.path.realpath( 'some_filename' ): [ 2, 5 ],
|
||||||
|
os.path.realpath( 'another_filename' ): [ 1 ]
|
||||||
|
}
|
||||||
|
|
||||||
|
with patch.dict( 'vim.buffers', buffers ):
|
||||||
|
vimsupport.CloseBuffersForFilename( 'some_filename' )
|
||||||
|
|
||||||
|
vim_command.assert_has_calls( [
|
||||||
|
call( 'silent! bwipeout! 2' ),
|
||||||
|
call( 'silent! bwipeout! 5' )
|
||||||
|
], any_order = True )
|
||||||
|
|
||||||
|
|
||||||
|
@patch( 'vim.command' )
|
||||||
|
@patch( 'vim.current' )
|
||||||
|
def OpenFilename_test( vim_current, vim_command ):
|
||||||
|
# Options used to open a logfile
|
||||||
|
options = {
|
||||||
|
'size': vimsupport.GetIntValue( '&previewheight' ),
|
||||||
|
'fix': True,
|
||||||
|
'watch': True,
|
||||||
|
'position': 'end'
|
||||||
|
}
|
||||||
|
|
||||||
|
vimsupport.OpenFilename( __file__, options )
|
||||||
|
|
||||||
|
vim_command.assert_has_calls( [
|
||||||
|
call( 'silent! 12split {0}'.format( __file__ ) ),
|
||||||
|
call( "exec "
|
||||||
|
"'au BufEnter <buffer> :silent! checktime {0}'".format( __file__ ) ),
|
||||||
|
call( 'silent! normal G zz' ),
|
||||||
|
call( 'silent! wincmd p' )
|
||||||
|
] )
|
||||||
|
|
||||||
|
vim_current.buffer.options.__setitem__.assert_has_calls( [
|
||||||
|
call( 'autoread', True ),
|
||||||
|
] )
|
||||||
|
|
||||||
|
vim_current.window.options.__setitem__.assert_has_calls( [
|
||||||
|
call( 'winfixheight', True )
|
||||||
|
] )
|
||||||
|
Loading…
Reference in New Issue
Block a user