Răsfoiți Sursa

Add tests for Vim file and buffer operations

Refactor Vim mocking.
micbou 9 ani în urmă
părinte
comite
f23cbae2a8
2 a modificat fișierele cu 103 adăugiri și 21 ștergeri
  1. 25 4
      python/ycm/test_utils.py
  2. 78 17
      python/ycm/tests/vimsupport_test.py

+ 25 - 4
python/ycm/test_utils.py

@@ -18,18 +18,23 @@
 # along with YouCompleteMe.  If not, see <http://www.gnu.org/licenses/>.
 
 from mock import MagicMock
+import re
 import sys
 
+
+BUFNR_REGEX = re.compile( r"bufnr\('(.+)', ([0-9]+)\)" )
+
 # 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,
-# and subsquent assignments to sys.modules[ 'vim' ] don't retrospectively update
-# them. The result is that while running the tests, we must assign only one
-# instance of MagicMock to sys.modules[ 'vim' ] and always return it.
+# and subsquent assignments to sys.modules[ 'vim' ] don't retrospectively
+# update them. The result is that while running the tests, we must assign only
+# one instance of MagicMock to sys.modules[ 'vim' ] and always return it.
 #
 # More explanation is available:
 # https://github.com/Valloric/YouCompleteMe/pull/1694
 VIM_MOCK = MagicMock()
 
+
 def MockVimModule():
   """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
@@ -55,8 +60,24 @@ def MockVimModule():
   def VimEval( value ):
     if value == "g:ycm_min_num_of_chars_for_completion":
       return 0
-    return ''
+    if value == "g:ycm_path_to_python_interpreter":
+      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 )
   sys.modules[ 'vim' ] = VIM_MOCK
 

+ 78 - 17
python/ycm/tests/vimsupport_test.py

@@ -22,7 +22,9 @@ MockVimModule()
 
 from ycm import vimsupport
 from nose.tools import eq_
+from hamcrest import assert_that, calling, raises, none
 from mock import MagicMock, call, patch
+import os
 
 
 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.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 )
 
   vimsupport.WriteToPreviewWindow( "test" )
@@ -615,9 +609,8 @@ def WriteToPreviewWindow_test( vim_current, vim_command, vim_eval ):
   ], any_order = True )
 
 
-@patch( 'vim.eval', side_effect=_Mock_tempname )
 @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 )
   vimsupport.WriteToPreviewWindow( "test\ntest2" )
 
@@ -625,10 +618,9 @@ def WriteToPreviewWindow_MultiLine_test( vim_current, vim_eval ):
       slice( None, None, None ), [ 'test', 'test2' ] )
 
 
-@patch( 'vim.eval', side_effect=_Mock_tempname )
 @patch( 'vim.command' )
 @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 )
 
   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()
 
 
-@patch( 'vim.eval', side_effect=_Mock_tempname )
 @patch( 'vim.command' )
 @patch( 'vim.current' )
-def WriteToPreviewWindow_JumpFail_MultiLine_test( vim_current,
-                                                  vim_command,
-                                                  vim_eval ):
+def WriteToPreviewWindow_JumpFail_MultiLine_test( vim_current, vim_command ):
 
   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.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 )
+  ] )