Переглянути джерело

Add JumpToLocation unicode tests

micbou 8 роки тому
батько
коміт
e5457affd8

+ 15 - 1
python/ycm/tests/__init__.py

@@ -29,11 +29,12 @@ import functools
 import os
 import requests
 import time
+import warnings
 
 from ycm.client.base_request import BaseRequest
 from ycm.youcompleteme import YouCompleteMe
 from ycmd import user_options_store
-from ycmd.utils import WaitUntilProcessIsTerminated
+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
@@ -84,10 +85,23 @@ 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

+ 17 - 2
python/ycm/tests/test_utils.py

@@ -91,6 +91,8 @@ def _MockGetBufferVariable( buffer_number, option ):
         return vim_buffer.filetype
       if option == 'changedtick':
         return vim_buffer.changedtick
+      if option == '&hid':
+        return vim_buffer.hidden
       return ''
   return ''
 
@@ -214,6 +216,7 @@ class VimBuffer( object ):
    - |contents|: list of lines representing the buffer contents;
    - |filetype|: buffer filetype. Empty string if no filetype is set;
    - |modified|: True if the buffer has unsaved changes, False otherwise;
+   - |hidden|  : True if the buffer is hidden, False otherwise;
    - |window|  : number of the buffer window. None if the buffer is hidden;
    - |omnifunc|: omni completion function used by the buffer."""
 
@@ -222,6 +225,7 @@ class VimBuffer( object ):
                       contents = [],
                       filetype = '',
                       modified = True,
+                      hidden = False,
                       window = None,
                       omnifunc = '' ):
     self.name = os.path.realpath( name ) if name else ''
@@ -229,7 +233,8 @@ class VimBuffer( object ):
     self.contents = contents
     self.filetype = filetype
     self.modified = modified
-    self.window = window
+    self.hidden = hidden
+    self.window = window if not hidden else None
     self.omnifunc = omnifunc
     self.changedtick = 1
 
@@ -287,7 +292,7 @@ def MockVimBuffers( buffers, current_buffer, cursor_position = ( 1, 1 ) ):
   with patch( 'vim.buffers', buffers ):
     with patch( 'vim.current.buffer', current_buffer ):
       with patch( 'vim.current.window.cursor', cursor_position ):
-        yield
+        yield VIM_MOCK
 
 
 def MockVimModule():
@@ -319,6 +324,16 @@ def MockVimModule():
   return VIM_MOCK
 
 
+class VimError( Exception ):
+
+  def __init__( self, code ):
+      self.code = code
+
+
+  def __str__( self ):
+      return repr( self.code )
+
+
 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.

+ 136 - 1
python/ycm/tests/vimsupport_test.py

@@ -27,7 +27,7 @@ from builtins import *  # noqa
 from ycm.tests import PathToTestFile
 from ycm.tests.test_utils import ( CurrentWorkingDirectory, ExtendedMock,
                                    MockVimBuffers, MockVimCommand,
-                                   MockVimModule, VimBuffer )
+                                   MockVimModule, VimBuffer, VimError )
 MockVimModule()
 
 from ycm import vimsupport
@@ -1602,3 +1602,138 @@ def EscapedFilepath_test():
        '/path/\ with\ /sp\ ac\ es' )
   eq_( vimsupport.EscapedFilepath( ' relative path/ with / spaces ' ),
        '\ relative\ path/\ with\ /\ spaces\ ' )
+
+
+@patch( 'ycmd.user_options_store._USER_OPTIONS',
+        { 'goto_buffer_command': 'same-buffer' } )
+@patch( 'vim.command', new_callable = ExtendedMock )
+def JumpToLocation_SameFile_SameBuffer_NoSwapFile_test( vim_command ):
+  # No 'u' prefix for the current buffer name string to simulate Vim returning
+  # bytes on Python 2 but unicode on Python 3.
+  current_buffer = VimBuffer( 'uni¢𐍈d€' )
+  with MockVimBuffers( [ current_buffer ], current_buffer ) as vim:
+    vimsupport.JumpToLocation( os.path.realpath( u'uni¢𐍈d€' ), 2, 5 )
+
+    assert_that( vim.current.window.cursor, equal_to( ( 2, 4 ) ) )
+    vim_command.assert_has_exact_calls( [
+      call( 'normal! m\'' ),
+      call( 'normal! zz' )
+    ] )
+
+
+@patch( 'ycmd.user_options_store._USER_OPTIONS',
+        { 'goto_buffer_command': 'same-buffer' } )
+@patch( 'vim.command', new_callable = ExtendedMock )
+def JumpToLocation_DifferentFile_SameBuffer_NoSwapFile_test( vim_command ):
+  current_buffer = VimBuffer( 'uni¢𐍈d€' )
+  with MockVimBuffers( [ current_buffer ], current_buffer ) as vim:
+    target_name = os.path.realpath( u'different_uni¢𐍈d€' )
+
+    vimsupport.JumpToLocation( target_name, 2, 5 )
+
+    assert_that( vim.current.window.cursor, equal_to( ( 2, 4 ) ) )
+    vim_command.assert_has_exact_calls( [
+      call( 'normal! m\'' ),
+      call( u'keepjumps split {0}'.format( target_name ) ),
+      call( 'normal! zz' )
+    ] )
+
+
+@patch( 'ycmd.user_options_store._USER_OPTIONS',
+        { 'goto_buffer_command': 'same-buffer' } )
+@patch( 'vim.error', VimError )
+@patch( 'vim.command',
+        side_effect = [ None, VimError( 'Unknown code' ), None ] )
+def JumpToLocation_DifferentFile_SameBuffer_SwapFile_Unexpected_test(
+    vim_command ):
+
+  current_buffer = VimBuffer( 'uni¢𐍈d€' )
+  with MockVimBuffers( [ current_buffer ], current_buffer ):
+    assert_that(
+      calling( vimsupport.JumpToLocation ).with_args(
+          os.path.realpath( u'different_uni¢𐍈d€' ), 2, 5 ),
+      raises( VimError, 'Unknown code' )
+    )
+
+
+@patch( 'ycmd.user_options_store._USER_OPTIONS',
+        { 'goto_buffer_command': 'same-buffer' } )
+@patch( 'vim.error', VimError )
+@patch( 'vim.command',
+        new_callable = ExtendedMock,
+        side_effect = [ None, VimError( 'E325' ), None ] )
+def JumpToLocation_DifferentFile_SameBuffer_SwapFile_Quit_test( vim_command ):
+  current_buffer = VimBuffer( 'uni¢𐍈d€' )
+  with MockVimBuffers( [ current_buffer ], current_buffer ):
+    target_name = os.path.realpath( u'different_uni¢𐍈d€' )
+
+    vimsupport.JumpToLocation( target_name, 2, 5 )
+
+    vim_command.assert_has_exact_calls( [
+      call( 'normal! m\'' ),
+      call( u'keepjumps split {0}'.format( target_name ) )
+    ] )
+
+
+@patch( 'ycmd.user_options_store._USER_OPTIONS',
+        { 'goto_buffer_command': 'same-buffer' } )
+@patch( 'vim.error', VimError )
+@patch( 'vim.command',
+        new_callable = ExtendedMock,
+        side_effect = [ None, KeyboardInterrupt, None ] )
+def JumpToLocation_DifferentFile_SameBuffer_SwapFile_Abort_test( vim_command ):
+  current_buffer = VimBuffer( 'uni¢𐍈d€' )
+  with MockVimBuffers( [ current_buffer ], current_buffer ):
+    target_name = os.path.realpath( u'different_uni¢𐍈d€' )
+
+    vimsupport.JumpToLocation( target_name, 2, 5 )
+
+    vim_command.assert_has_exact_calls( [
+      call( 'normal! m\'' ),
+      call( u'keepjumps split {0}'.format( target_name ) )
+    ] )
+
+
+@patch( 'ycmd.user_options_store._USER_OPTIONS',
+        { 'goto_buffer_command': 'new-or-existing-tab' } )
+@patch( 'vim.command', new_callable = ExtendedMock )
+def JumpToLocation_DifferentFile_NewOrExistingTab_NotAlreadyOpened_test(
+    vim_command ):
+
+  current_buffer = VimBuffer( 'uni¢𐍈d€' )
+  with MockVimBuffers( [ current_buffer ], current_buffer ):
+    target_name = os.path.realpath( u'different_uni¢𐍈d€' )
+
+    vimsupport.JumpToLocation( target_name, 2, 5 )
+
+    vim_command.assert_has_exact_calls( [
+      call( 'normal! m\'' ),
+      call( u'keepjumps tabedit {0}'.format( target_name ) ),
+      call( 'normal! zz' )
+    ] )
+
+
+@patch( 'ycmd.user_options_store._USER_OPTIONS',
+        { 'goto_buffer_command': 'new-or-existing-tab' } )
+@patch( 'vim.command', new_callable = ExtendedMock )
+def JumpToLocation_DifferentFile_NewOrExistingTab_AlreadyOpened_test(
+    vim_command ):
+
+  current_buffer = VimBuffer( 'uni¢𐍈d€' )
+  different_buffer = VimBuffer( 'different_uni¢𐍈d€' )
+  current_window = MagicMock( buffer = current_buffer )
+  different_window = MagicMock( buffer = different_buffer )
+  current_tab = MagicMock( windows = [ current_window, different_window ] )
+  with patch( 'vim.tabpages', [ current_tab ] ):
+    with MockVimBuffers( [ current_buffer, different_buffer ],
+                         current_buffer ) as vim:
+      vimsupport.JumpToLocation( os.path.realpath( u'different_uni¢𐍈d€' ),
+                                 2, 5 )
+
+      assert_that( vim.current.tabpage, equal_to( current_tab ) )
+      assert_that( vim.current.window, equal_to( different_window ) )
+      assert_that( vim.current.window.cursor, equal_to( ( 2, 4 ) ) )
+      vim_command.assert_has_exact_calls( [
+        call( 'normal! m\'' ),
+        call( 'normal! zz' )
+      ] )