diff --git a/pytest.ini b/pytest.ini
deleted file mode 100644
index 5981153562..0000000000
--- a/pytest.ini
+++ /dev/null
@@ -1,7 +0,0 @@
-[pytest]
-python_functions = *_test
-python_classes = *_test
-xfail_strict = true
-log_level = debug
-log_date_format = "%Y-%m-%d %H:%M:%S"
-log_format = "%(asctime)s - %(levelname)s - %(message)s"
diff --git a/python/test_requirements.txt b/python/test_requirements.txt
index d3b500518d..3a0bc1e34c 100644
--- a/python/test_requirements.txt
+++ b/python/test_requirements.txt
@@ -6,5 +6,3 @@ codecov >= 2.0.5
coverage <5.0
click <8.0.0
covimerage >= 0.2.0
-pytest
-pytest-cov
diff --git a/python/ycm/tests/__init__.py b/python/ycm/tests/__init__.py
index 3202f80b56..b5a85f9113 100644
--- a/python/ycm/tests/__init__.py
+++ b/python/ycm/tests/__init__.py
@@ -16,9 +16,118 @@
# along with YouCompleteMe. If not, see .
import os
-from ycm.tests.conftest import * # noqa
+from ycm.tests.test_utils import MockVimModule
+MockVimModule()
+
+import contextlib
+import functools
+import time
+from urllib.error import HTTPError, URLError
+
+from ycm.client.base_request import BaseRequest
+from ycm.tests import test_utils
+from ycm.youcompleteme import YouCompleteMe
+from ycmd.utils import CloseStandardStreams, WaitUntilProcessIsTerminated
def PathToTestFile( *args ):
dir_of_current_script = os.path.dirname( os.path.abspath( __file__ ) )
return os.path.join( dir_of_current_script, 'testdata', *args )
+
+
+# The default options which are required for a working YouCompleteMe object.
+DEFAULT_CLIENT_OPTIONS = {
+ # YCM options
+ 'g:ycm_log_level': 'info',
+ 'g:ycm_keep_logfiles': 0,
+ 'g:ycm_extra_conf_vim_data': [],
+ 'g:ycm_server_python_interpreter': '',
+ 'g:ycm_show_diagnostics_ui': 1,
+ 'g:ycm_enable_diagnostic_signs': 1,
+ 'g:ycm_enable_diagnostic_highlighting': 0,
+ 'g:ycm_echo_current_diagnostic': 1,
+ 'g:ycm_filter_diagnostics': {},
+ 'g:ycm_always_populate_location_list': 0,
+ 'g:ycm_collect_identifiers_from_tags_files': 0,
+ 'g:ycm_seed_identifiers_with_syntax': 0,
+ 'g:ycm_goto_buffer_command': 'same-buffer',
+ 'g:ycm_update_diagnostics_in_insert_mode': 1,
+ # ycmd options
+ 'g:ycm_auto_trigger': 1,
+ 'g:ycm_min_num_of_chars_for_completion': 2,
+ 'g:ycm_semantic_triggers': {},
+ 'g:ycm_filetype_specific_completion_to_disable': { 'gitcommit': 1 },
+ 'g:ycm_max_num_candidates': 50,
+ 'g:ycm_max_diagnostics_to_display': 30,
+ 'g:ycm_disable_signature_help': 0,
+}
+
+
+@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 '
+ f'for { timeout } seconds, aborting.' )
+ if _IsReady():
+ return
+ except ( URLError, HTTPError ):
+ pass
+ finally:
+ time.sleep( 0.1 )
+
+
+def StopServer( ycm ):
+ try:
+ ycm.OnVimLeave()
+ WaitUntilProcessIsTerminated( ycm._server_popen )
+ CloseStandardStreams( ycm._server_popen )
+ except Exception:
+ pass
+
+
+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.
+
+ 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_utils.VIM_MATCHES_FOR_WINDOW.clear()
+ return test( args[ 0 ], ycm, *args[ 1: ], **kwargs )
+ finally:
+ StopServer( ycm )
+ return Wrapper
+ return Decorator
diff --git a/python/ycm/tests/base_test.py b/python/ycm/tests/base_test.py
index 82e2e7d6fd..534ce4eaf6 100644
--- a/python/ycm/tests/base_test.py
+++ b/python/ycm/tests/base_test.py
@@ -18,6 +18,7 @@
import contextlib
from hamcrest import assert_that, equal_to
+from unittest import TestCase
from unittest.mock import patch
from ycm.tests.test_utils import MockVimModule
@@ -45,263 +46,264 @@ def MockTextAfterCursor( text ):
yield
-def AdjustCandidateInsertionText_Basic_test():
- with MockTextAfterCursor( 'bar' ):
- assert_that( [ { 'word': 'foo', 'abbr': 'foobar' } ],
- equal_to( base.AdjustCandidateInsertionText( [
- { 'word': 'foobar', 'abbr': '' } ] ) ) )
+class BaseTest( TestCase ):
+ def test_AdjustCandidateInsertionText_Basic( self ):
+ with MockTextAfterCursor( 'bar' ):
+ assert_that( [ { 'word': 'foo', 'abbr': 'foobar' } ],
+ equal_to( base.AdjustCandidateInsertionText( [
+ { 'word': 'foobar', 'abbr': '' } ] ) ) )
-def AdjustCandidateInsertionText_ParenInTextAfterCursor_test():
- with MockTextAfterCursor( 'bar(zoo' ):
- assert_that( [ { 'word': 'foo', 'abbr': 'foobar' } ],
- equal_to( base.AdjustCandidateInsertionText( [
- { 'word': 'foobar', 'abbr': '' } ] ) ) )
+ def test_AdjustCandidateInsertionText_ParenInTextAfterCursor( self ):
+ with MockTextAfterCursor( 'bar(zoo' ):
+ assert_that( [ { 'word': 'foo', 'abbr': 'foobar' } ],
+ equal_to( base.AdjustCandidateInsertionText( [
+ { 'word': 'foobar', 'abbr': '' } ] ) ) )
-def AdjustCandidateInsertionText_PlusInTextAfterCursor_test():
- with MockTextAfterCursor( 'bar+zoo' ):
- assert_that( [ { 'word': 'foo', 'abbr': 'foobar' } ],
- equal_to( base.AdjustCandidateInsertionText( [
- { 'word': 'foobar', 'abbr': '' } ] ) ) )
+ def test_AdjustCandidateInsertionText_PlusInTextAfterCursor( self ):
+ with MockTextAfterCursor( 'bar+zoo' ):
+ assert_that( [ { 'word': 'foo', 'abbr': 'foobar' } ],
+ equal_to( base.AdjustCandidateInsertionText( [
+ { 'word': 'foobar', 'abbr': '' } ] ) ) )
-def AdjustCandidateInsertionText_WhitespaceInTextAfterCursor_test():
- with MockTextAfterCursor( 'bar zoo' ):
- assert_that( [ { 'word': 'foo', 'abbr': 'foobar' } ],
- equal_to( base.AdjustCandidateInsertionText( [
- { 'word': 'foobar', 'abbr': '' } ] ) ) )
+ def test_AdjustCandidateInsertionText_WhitespaceInTextAfterCursor( self ):
+ with MockTextAfterCursor( 'bar zoo' ):
+ assert_that( [ { 'word': 'foo', 'abbr': 'foobar' } ],
+ equal_to( base.AdjustCandidateInsertionText( [
+ { 'word': 'foobar', 'abbr': '' } ] ) ) )
-def AdjustCandidateInsertionText_MoreThanWordMatchingAfterCursor_test():
- with MockTextAfterCursor( 'bar.h' ):
- assert_that( [ { 'word': 'foo', 'abbr': 'foobar.h' } ],
- equal_to( base.AdjustCandidateInsertionText( [
- { 'word': 'foobar.h', 'abbr': '' } ] ) ) )
+ def test_AdjustCandidateInsertionText_MoreThanWordMatchingAfterCursor( self ):
+ with MockTextAfterCursor( 'bar.h' ):
+ assert_that( [ { 'word': 'foo', 'abbr': 'foobar.h' } ],
+ equal_to( base.AdjustCandidateInsertionText( [
+ { 'word': 'foobar.h', 'abbr': '' } ] ) ) )
- with MockTextAfterCursor( 'bar(zoo' ):
- assert_that( [ { 'word': 'foo', 'abbr': 'foobar(zoo' } ],
- equal_to( base.AdjustCandidateInsertionText( [
- { 'word': 'foobar(zoo', 'abbr': '' } ] ) ) )
+ with MockTextAfterCursor( 'bar(zoo' ):
+ assert_that( [ { 'word': 'foo', 'abbr': 'foobar(zoo' } ],
+ equal_to( base.AdjustCandidateInsertionText( [
+ { 'word': 'foobar(zoo', 'abbr': '' } ] ) ) )
-def AdjustCandidateInsertionText_NotSuffix_test():
- with MockTextAfterCursor( 'bar' ):
- assert_that( [ { 'word': 'foofoo', 'abbr': 'foofoo' } ],
- equal_to( base.AdjustCandidateInsertionText( [
- { 'word': 'foofoo', 'abbr': '' } ] ) ) )
+ def test_AdjustCandidateInsertionText_NotSuffix( self ):
+ with MockTextAfterCursor( 'bar' ):
+ assert_that( [ { 'word': 'foofoo', 'abbr': 'foofoo' } ],
+ equal_to( base.AdjustCandidateInsertionText( [
+ { 'word': 'foofoo', 'abbr': '' } ] ) ) )
-def AdjustCandidateInsertionText_NothingAfterCursor_test():
- with MockTextAfterCursor( '' ):
- assert_that( [ { 'word': 'foofoo', 'abbr': '' },
- { 'word': 'zobar', 'abbr': '' } ],
- equal_to( base.AdjustCandidateInsertionText( [
- { 'word': 'foofoo', 'abbr': '' },
- { 'word': 'zobar', 'abbr': '' } ] ) ) )
+ def test_AdjustCandidateInsertionText_NothingAfterCursor( self ):
+ with MockTextAfterCursor( '' ):
+ assert_that( [ { 'word': 'foofoo', 'abbr': '' },
+ { 'word': 'zobar', 'abbr': '' } ],
+ equal_to( base.AdjustCandidateInsertionText( [
+ { 'word': 'foofoo', 'abbr': '' },
+ { 'word': 'zobar', 'abbr': '' } ] ) ) )
-def AdjustCandidateInsertionText_MultipleStrings_test():
- with MockTextAfterCursor( 'bar' ):
- assert_that( [ { 'word': 'foo', 'abbr': 'foobar' },
- { 'word': 'zo', 'abbr': 'zobar' },
- { 'word': 'q', 'abbr': 'qbar' },
- { 'word': '', 'abbr': 'bar' }, ],
- equal_to( base.AdjustCandidateInsertionText( [
- { 'word': 'foobar', 'abbr': '' },
- { 'word': 'zobar', 'abbr': '' },
- { 'word': 'qbar', 'abbr': '' },
- { 'word': 'bar', 'abbr': '' } ] ) ) )
+ def test_AdjustCandidateInsertionText_MultipleStrings( self ):
+ with MockTextAfterCursor( 'bar' ):
+ assert_that( [ { 'word': 'foo', 'abbr': 'foobar' },
+ { 'word': 'zo', 'abbr': 'zobar' },
+ { 'word': 'q', 'abbr': 'qbar' },
+ { 'word': '', 'abbr': 'bar' }, ],
+ equal_to( base.AdjustCandidateInsertionText( [
+ { 'word': 'foobar', 'abbr': '' },
+ { 'word': 'zobar', 'abbr': '' },
+ { 'word': 'qbar', 'abbr': '' },
+ { 'word': 'bar', 'abbr': '' } ] ) ) )
-def AdjustCandidateInsertionText_DontTouchAbbr_test():
- with MockTextAfterCursor( 'bar' ):
- assert_that( [ { 'word': 'foo', 'abbr': '1234' } ],
- equal_to( base.AdjustCandidateInsertionText( [
- { 'word': 'foobar', 'abbr': '1234' } ] ) ) )
+ def test_AdjustCandidateInsertionText_DontTouchAbbr( self ):
+ with MockTextAfterCursor( 'bar' ):
+ assert_that( [ { 'word': 'foo', 'abbr': '1234' } ],
+ equal_to( base.AdjustCandidateInsertionText( [
+ { 'word': 'foobar', 'abbr': '1234' } ] ) ) )
-def AdjustCandidateInsertionText_NoAbbr_test():
- with MockTextAfterCursor( 'bar' ):
- assert_that( [ { 'word': 'foo', 'abbr': 'foobar' } ],
- equal_to( base.AdjustCandidateInsertionText( [
- { 'word': 'foobar' } ] ) ) )
+ def test_AdjustCandidateInsertionText_NoAbbr( self ):
+ with MockTextAfterCursor( 'bar' ):
+ assert_that( [ { 'word': 'foo', 'abbr': 'foobar' } ],
+ equal_to( base.AdjustCandidateInsertionText( [
+ { 'word': 'foobar' } ] ) ) )
-def OverlapLength_Basic_test():
- assert_that( 3, equal_to( base.OverlapLength( 'foo bar', 'bar zoo' ) ) )
- assert_that( 3, equal_to( base.OverlapLength( 'foobar', 'barzoo' ) ) )
+ def test_OverlapLength_Basic( self ):
+ assert_that( 3, equal_to( base.OverlapLength( 'foo bar', 'bar zoo' ) ) )
+ assert_that( 3, equal_to( base.OverlapLength( 'foobar', 'barzoo' ) ) )
-def OverlapLength_BasicWithUnicode_test():
- assert_that( 3, equal_to( base.OverlapLength( 'bar fäö', 'fäö bar' ) ) )
- assert_that( 3, equal_to( base.OverlapLength( 'zoofäö', 'fäözoo' ) ) )
+ def test_OverlapLength_BasicWithUnicode( self ):
+ assert_that( 3, equal_to( base.OverlapLength( 'bar fäö', 'fäö bar' ) ) )
+ assert_that( 3, equal_to( base.OverlapLength( 'zoofäö', 'fäözoo' ) ) )
-def OverlapLength_OneCharOverlap_test():
- assert_that( 1, equal_to( base.OverlapLength( 'foo b', 'b zoo' ) ) )
+ def test_OverlapLength_OneCharOverlap( self ):
+ assert_that( 1, equal_to( base.OverlapLength( 'foo b', 'b zoo' ) ) )
-def OverlapLength_SameStrings_test():
- assert_that( 6, equal_to( base.OverlapLength( 'foobar', 'foobar' ) ) )
+ def test_OverlapLength_SameStrings( self ):
+ assert_that( 6, equal_to( base.OverlapLength( 'foobar', 'foobar' ) ) )
-def OverlapLength_Substring_test():
- assert_that( 6, equal_to( base.OverlapLength( 'foobar', 'foobarzoo' ) ) )
- assert_that( 6, equal_to( base.OverlapLength( 'zoofoobar', 'foobar' ) ) )
+ def test_OverlapLength_Substring( self ):
+ assert_that( 6, equal_to( base.OverlapLength( 'foobar', 'foobarzoo' ) ) )
+ assert_that( 6, equal_to( base.OverlapLength( 'zoofoobar', 'foobar' ) ) )
-def OverlapLength_LongestOverlap_test():
- assert_that( 7, equal_to( base.OverlapLength( 'bar foo foo',
- 'foo foo bar' ) ) )
+ def test_OverlapLength_LongestOverlap( self ):
+ assert_that( 7, equal_to( base.OverlapLength( 'bar foo foo',
+ 'foo foo bar' ) ) )
-def OverlapLength_EmptyInput_test():
- assert_that( 0, equal_to( base.OverlapLength( '', 'goobar' ) ) )
- assert_that( 0, equal_to( base.OverlapLength( 'foobar', '' ) ) )
- assert_that( 0, equal_to( base.OverlapLength( '', '' ) ) )
+ def test_OverlapLength_EmptyInput( self ):
+ assert_that( 0, equal_to( base.OverlapLength( '', 'goobar' ) ) )
+ assert_that( 0, equal_to( base.OverlapLength( 'foobar', '' ) ) )
+ assert_that( 0, equal_to( base.OverlapLength( '', '' ) ) )
-def OverlapLength_NoOverlap_test():
- assert_that( 0, equal_to( base.OverlapLength( 'foobar', 'goobar' ) ) )
- assert_that( 0, equal_to( base.OverlapLength( 'foobar', '(^($@#$#@' ) ) )
- assert_that( 0, equal_to( base.OverlapLength( 'foo bar zoo',
- 'foo zoo bar' ) ) )
+ def test_OverlapLength_NoOverlap( self ):
+ assert_that( 0, equal_to( base.OverlapLength( 'foobar', 'goobar' ) ) )
+ assert_that( 0, equal_to( base.OverlapLength( 'foobar', '(^($@#$#@' ) ) )
+ assert_that( 0, equal_to( base.OverlapLength( 'foo bar zoo',
+ 'foo zoo bar' ) ) )
-def LastEnteredCharIsIdentifierChar_Basic_test():
- with MockCurrentFiletypes():
- with MockCurrentColumnAndLineContents( 3, 'abc' ):
- assert_that( base.LastEnteredCharIsIdentifierChar() )
+ def test_LastEnteredCharIsIdentifierChar_Basic( self ):
+ with MockCurrentFiletypes():
+ with MockCurrentColumnAndLineContents( 3, 'abc' ):
+ assert_that( base.LastEnteredCharIsIdentifierChar() )
- with MockCurrentColumnAndLineContents( 2, 'abc' ):
- assert_that( base.LastEnteredCharIsIdentifierChar() )
+ with MockCurrentColumnAndLineContents( 2, 'abc' ):
+ assert_that( base.LastEnteredCharIsIdentifierChar() )
- with MockCurrentColumnAndLineContents( 1, 'abc' ):
- assert_that( base.LastEnteredCharIsIdentifierChar() )
+ with MockCurrentColumnAndLineContents( 1, 'abc' ):
+ assert_that( base.LastEnteredCharIsIdentifierChar() )
-def LastEnteredCharIsIdentifierChar_FiletypeHtml_test():
- with MockCurrentFiletypes( [ 'html' ] ):
- with MockCurrentColumnAndLineContents( 3, 'ab-' ):
- assert_that( base.LastEnteredCharIsIdentifierChar() )
+ def test_LastEnteredCharIsIdentifierChar_FiletypeHtml( self ):
+ with MockCurrentFiletypes( [ 'html' ] ):
+ with MockCurrentColumnAndLineContents( 3, 'ab-' ):
+ assert_that( base.LastEnteredCharIsIdentifierChar() )
-def LastEnteredCharIsIdentifierChar_ColumnIsZero_test():
- with MockCurrentColumnAndLineContents( 0, 'abc' ):
- assert_that( not base.LastEnteredCharIsIdentifierChar() )
-
-
-def LastEnteredCharIsIdentifierChar_LineEmpty_test():
- with MockCurrentFiletypes():
- with MockCurrentColumnAndLineContents( 3, '' ):
+ def test_LastEnteredCharIsIdentifierChar_ColumnIsZero( self ):
+ with MockCurrentColumnAndLineContents( 0, 'abc' ):
assert_that( not base.LastEnteredCharIsIdentifierChar() )
- with MockCurrentColumnAndLineContents( 0, '' ):
- assert_that( not base.LastEnteredCharIsIdentifierChar() )
+ def test_LastEnteredCharIsIdentifierChar_LineEmpty( self ):
+ with MockCurrentFiletypes():
+ with MockCurrentColumnAndLineContents( 3, '' ):
+ assert_that( not base.LastEnteredCharIsIdentifierChar() )
-def LastEnteredCharIsIdentifierChar_NotIdentChar_test():
- with MockCurrentFiletypes():
- with MockCurrentColumnAndLineContents( 3, 'ab;' ):
- assert_that( not base.LastEnteredCharIsIdentifierChar() )
+ with MockCurrentColumnAndLineContents( 0, '' ):
+ assert_that( not base.LastEnteredCharIsIdentifierChar() )
- with MockCurrentColumnAndLineContents( 1, ';' ):
- assert_that( not base.LastEnteredCharIsIdentifierChar() )
- with MockCurrentColumnAndLineContents( 3, 'ab-' ):
- assert_that( not base.LastEnteredCharIsIdentifierChar() )
+ def test_LastEnteredCharIsIdentifierChar_NotIdentChar( self ):
+ with MockCurrentFiletypes():
+ with MockCurrentColumnAndLineContents( 3, 'ab;' ):
+ assert_that( not base.LastEnteredCharIsIdentifierChar() )
+ with MockCurrentColumnAndLineContents( 1, ';' ):
+ assert_that( not base.LastEnteredCharIsIdentifierChar() )
-def LastEnteredCharIsIdentifierChar_Unicode_test():
- with MockCurrentFiletypes():
- # CurrentColumn returns a byte offset and character ø is 2 bytes length.
- with MockCurrentColumnAndLineContents( 5, 'føo(' ):
- assert_that( not base.LastEnteredCharIsIdentifierChar() )
+ with MockCurrentColumnAndLineContents( 3, 'ab-' ):
+ assert_that( not base.LastEnteredCharIsIdentifierChar() )
- with MockCurrentColumnAndLineContents( 4, 'føo(' ):
- assert_that( base.LastEnteredCharIsIdentifierChar() )
- with MockCurrentColumnAndLineContents( 3, 'føo(' ):
- assert_that( base.LastEnteredCharIsIdentifierChar() )
+ def test_LastEnteredCharIsIdentifierChar_Unicode( self ):
+ with MockCurrentFiletypes():
+ # CurrentColumn returns a byte offset and character ø is 2 bytes length.
+ with MockCurrentColumnAndLineContents( 5, 'føo(' ):
+ assert_that( not base.LastEnteredCharIsIdentifierChar() )
- with MockCurrentColumnAndLineContents( 1, 'føo(' ):
- assert_that( base.LastEnteredCharIsIdentifierChar() )
+ with MockCurrentColumnAndLineContents( 4, 'føo(' ):
+ assert_that( base.LastEnteredCharIsIdentifierChar() )
+ with MockCurrentColumnAndLineContents( 3, 'føo(' ):
+ assert_that( base.LastEnteredCharIsIdentifierChar() )
-def CurrentIdentifierFinished_Basic_test():
- with MockCurrentFiletypes():
- with MockCurrentColumnAndLineContents( 3, 'ab;' ):
- assert_that( base.CurrentIdentifierFinished() )
+ with MockCurrentColumnAndLineContents( 1, 'føo(' ):
+ assert_that( base.LastEnteredCharIsIdentifierChar() )
- with MockCurrentColumnAndLineContents( 2, 'ab;' ):
- assert_that( not base.CurrentIdentifierFinished() )
- with MockCurrentColumnAndLineContents( 1, 'ab;' ):
- assert_that( not base.CurrentIdentifierFinished() )
+ def test_CurrentIdentifierFinished_Basic( self ):
+ with MockCurrentFiletypes():
+ with MockCurrentColumnAndLineContents( 3, 'ab;' ):
+ assert_that( base.CurrentIdentifierFinished() )
+ with MockCurrentColumnAndLineContents( 2, 'ab;' ):
+ assert_that( not base.CurrentIdentifierFinished() )
-def CurrentIdentifierFinished_NothingBeforeColumn_test():
- with MockCurrentColumnAndLineContents( 0, 'ab;' ):
- assert_that( base.CurrentIdentifierFinished() )
+ with MockCurrentColumnAndLineContents( 1, 'ab;' ):
+ assert_that( not base.CurrentIdentifierFinished() )
- with MockCurrentColumnAndLineContents( 0, '' ):
- assert_that( base.CurrentIdentifierFinished() )
+ def test_CurrentIdentifierFinished_NothingBeforeColumn( self ):
+ with MockCurrentColumnAndLineContents( 0, 'ab;' ):
+ assert_that( base.CurrentIdentifierFinished() )
-def CurrentIdentifierFinished_InvalidColumn_test():
- with MockCurrentFiletypes():
- with MockCurrentColumnAndLineContents( 5, '' ):
+ with MockCurrentColumnAndLineContents( 0, '' ):
assert_that( base.CurrentIdentifierFinished() )
- with MockCurrentColumnAndLineContents( 5, 'abc' ):
- assert_that( not base.CurrentIdentifierFinished() )
- with MockCurrentColumnAndLineContents( 4, 'ab;' ):
- assert_that( base.CurrentIdentifierFinished() )
+ def test_CurrentIdentifierFinished_InvalidColumn( self ):
+ with MockCurrentFiletypes():
+ with MockCurrentColumnAndLineContents( 5, '' ):
+ assert_that( base.CurrentIdentifierFinished() )
+ with MockCurrentColumnAndLineContents( 5, 'abc' ):
+ assert_that( not base.CurrentIdentifierFinished() )
-def CurrentIdentifierFinished_InMiddleOfLine_test():
- with MockCurrentFiletypes():
- with MockCurrentColumnAndLineContents( 4, 'bar.zoo' ):
- assert_that( base.CurrentIdentifierFinished() )
+ with MockCurrentColumnAndLineContents( 4, 'ab;' ):
+ assert_that( base.CurrentIdentifierFinished() )
- with MockCurrentColumnAndLineContents( 4, 'bar(zoo' ):
- assert_that( base.CurrentIdentifierFinished() )
- with MockCurrentColumnAndLineContents( 4, 'bar-zoo' ):
- assert_that( base.CurrentIdentifierFinished() )
+ def test_CurrentIdentifierFinished_InMiddleOfLine( self ):
+ with MockCurrentFiletypes():
+ with MockCurrentColumnAndLineContents( 4, 'bar.zoo' ):
+ assert_that( base.CurrentIdentifierFinished() )
+ with MockCurrentColumnAndLineContents( 4, 'bar(zoo' ):
+ assert_that( base.CurrentIdentifierFinished() )
-def CurrentIdentifierFinished_Html_test():
- with MockCurrentFiletypes( [ 'html' ] ):
- with MockCurrentColumnAndLineContents( 4, 'bar-zoo' ):
- assert_that( not base.CurrentIdentifierFinished() )
+ with MockCurrentColumnAndLineContents( 4, 'bar-zoo' ):
+ assert_that( base.CurrentIdentifierFinished() )
-def CurrentIdentifierFinished_WhitespaceOnly_test():
- with MockCurrentFiletypes():
- with MockCurrentColumnAndLineContents( 1, '\n' ):
- assert_that( base.CurrentIdentifierFinished() )
+ def test_CurrentIdentifierFinished_Html( self ):
+ with MockCurrentFiletypes( [ 'html' ] ):
+ with MockCurrentColumnAndLineContents( 4, 'bar-zoo' ):
+ assert_that( not base.CurrentIdentifierFinished() )
- with MockCurrentColumnAndLineContents( 3, '\n ' ):
- assert_that( base.CurrentIdentifierFinished() )
- with MockCurrentColumnAndLineContents( 3, '\t\t\t\t' ):
- assert_that( base.CurrentIdentifierFinished() )
+ def test_CurrentIdentifierFinished_WhitespaceOnly( self ):
+ with MockCurrentFiletypes():
+ with MockCurrentColumnAndLineContents( 1, '\n' ):
+ assert_that( base.CurrentIdentifierFinished() )
+ with MockCurrentColumnAndLineContents( 3, '\n ' ):
+ assert_that( base.CurrentIdentifierFinished() )
-def CurrentIdentifierFinished_Unicode_test():
- with MockCurrentFiletypes():
- # CurrentColumn returns a byte offset and character ø is 2 bytes length.
- with MockCurrentColumnAndLineContents( 6, 'føo ' ):
- assert_that( base.CurrentIdentifierFinished() )
+ with MockCurrentColumnAndLineContents( 3, '\t\t\t\t' ):
+ assert_that( base.CurrentIdentifierFinished() )
- with MockCurrentColumnAndLineContents( 5, 'føo ' ):
- assert_that( base.CurrentIdentifierFinished() )
- with MockCurrentColumnAndLineContents( 4, 'føo ' ):
- assert_that( not base.CurrentIdentifierFinished() )
+ def test_CurrentIdentifierFinished_Unicode( self ):
+ with MockCurrentFiletypes():
+ # CurrentColumn returns a byte offset and character ø is 2 bytes length.
+ with MockCurrentColumnAndLineContents( 6, 'føo ' ):
+ assert_that( base.CurrentIdentifierFinished() )
+
+ with MockCurrentColumnAndLineContents( 5, 'føo ' ):
+ assert_that( base.CurrentIdentifierFinished() )
+
+ with MockCurrentColumnAndLineContents( 4, 'føo ' ):
+ assert_that( not base.CurrentIdentifierFinished() )
- with MockCurrentColumnAndLineContents( 3, 'føo ' ):
- assert_that( not base.CurrentIdentifierFinished() )
+ with MockCurrentColumnAndLineContents( 3, 'føo ' ):
+ assert_that( not base.CurrentIdentifierFinished() )
diff --git a/python/ycm/tests/client/base_request_test.py b/python/ycm/tests/client/base_request_test.py
index e31f9f69ce..1ad5a06034 100644
--- a/python/ycm/tests/client/base_request_test.py
+++ b/python/ycm/tests/client/base_request_test.py
@@ -19,22 +19,24 @@
MockVimModule()
from hamcrest import assert_that, has_entry
+from unittest import TestCase
from unittest.mock import patch
from ycm.client.base_request import BuildRequestData
-@patch( 'ycm.client.base_request.GetCurrentDirectory',
- return_value = '/some/dir' )
-def BuildRequestData_AddWorkingDir_test( *args ):
- current_buffer = VimBuffer( 'foo' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- assert_that( BuildRequestData(), has_entry( 'working_dir', '/some/dir' ) )
+class BaseRequestTest( TestCase ):
+ @patch( 'ycm.client.base_request.GetCurrentDirectory',
+ return_value = '/some/dir' )
+ def test_BuildRequestData_AddWorkingDir( self, *args ):
+ current_buffer = VimBuffer( 'foo' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ assert_that( BuildRequestData(), has_entry( 'working_dir', '/some/dir' ) )
-@patch( 'ycm.client.base_request.GetCurrentDirectory',
- return_value = '/some/dir' )
-def BuildRequestData_AddWorkingDirWithFileName_test( *args ):
- current_buffer = VimBuffer( 'foo' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- assert_that( BuildRequestData( current_buffer.number ),
- has_entry( 'working_dir', '/some/dir' ) )
+ @patch( 'ycm.client.base_request.GetCurrentDirectory',
+ return_value = '/some/dir' )
+ def test_BuildRequestData_AddWorkingDirWithFileName( self, *args ):
+ current_buffer = VimBuffer( 'foo' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ assert_that( BuildRequestData( current_buffer.number ),
+ has_entry( 'working_dir', '/some/dir' ) )
diff --git a/python/ycm/tests/client/command_request_test.py b/python/ycm/tests/client/command_request_test.py
index 784c8a8d92..7af6e4852e 100644
--- a/python/ycm/tests/client/command_request_test.py
+++ b/python/ycm/tests/client/command_request_test.py
@@ -19,8 +19,8 @@
MockVimModule()
import json
-import pytest
from hamcrest import assert_that
+from unittest import TestCase
from unittest.mock import patch, call
from ycm.client.command_request import CommandRequest
@@ -87,25 +87,25 @@ def GoToListTest( command, response ):
MULTI_FIXIT_SECOND_CHUNKS = MULTI_FIXIT[ 'fixits' ][ 1 ][ 'chunks' ]
-class GoToResponse_QuickFix_test:
+class GoToResponse_QuickFixTest( TestCase ):
"""This class tests the generation of QuickFix lists for GoTo responses which
return multiple locations, such as the Python completer and JavaScript
completer. It mostly proves that we use 1-based indexing for the column
number."""
- def setup_method( self ):
+ def setUp( self ):
self._request = CommandRequest( [ 'GoToTest' ] )
- def teardown_method( self ):
+ def tearDown( self ):
self._request = None
- def GoTo_EmptyList_test( self ):
+ def test_GoTo_EmptyList( self ):
self._CheckGoToList( [], [] )
- def GoTo_SingleItem_List_test( self ):
+ def test_GoTo_SingleItem_List( self ):
self._CheckGoToList( [ {
'filepath': 'dummy_file',
'line_num': 10,
@@ -119,7 +119,7 @@ def GoTo_SingleItem_List_test( self ):
} ] )
- def GoTo_MultiItem_List_test( self ):
+ def test_GoTo_MultiItem_List( self ):
self._CheckGoToList( [ {
'filepath': 'dummy_file',
'line_num': 10,
@@ -174,15 +174,9 @@ def _CheckGoToList( self,
set_fitting_height.assert_called_once_with()
-class Response_Detection_test:
+class Response_Detection_Test( TestCase ):
- @pytest.mark.parametrize( 'command,response', [
- [ 'AnythingYouLike', True ],
- [ 'GoToEvenWorks', 10 ],
- [ 'FixItWorks', 'String!' ],
- [ 'and8434fd andy garbag!', 10.3 ],
- ] )
- def BasicResponse_test( self, command, response ):
+ def test_BasicResponse( self ):
def _BasicResponseTest( command, response ):
with patch( 'vim.command' ) as vim_command:
request = CommandRequest( [ command ] )
@@ -190,13 +184,16 @@ def _BasicResponseTest( command, response ):
request.RunPostCommandActionsIfNeeded( 'belowright' )
vim_command.assert_called_with( f"echo '{ response }'" )
- _BasicResponseTest( command, response )
+ for command, response in [
+ [ 'AnythingYouLike', True ],
+ [ 'GoToEvenWorks', 10 ],
+ [ 'FixItWorks', 'String!' ],
+ [ 'and8434fd andy garbag!', 10.3 ],
+ ]:
+ with self.subTest( command = command, response = response ):
+ _BasicResponseTest( command, response )
- @pytest.mark.parametrize( 'command', [ 'FixIt',
- 'Refactor',
- 'GoToHell',
- 'any_old_garbade!!!21' ] )
- def FixIt_Response_Empty_test( self, command ):
+ def test_FixIt_Response_Empty( self ):
# Ensures we recognise and handle fixit responses which indicate that there
# are no fixits available
def EmptyFixItTest( command ):
@@ -212,27 +209,13 @@ def EmptyFixItTest( command ):
'No fixits found for current line', warning = False )
replace_chunks.assert_not_called()
- EmptyFixItTest( command )
+ for command in [ 'FixIt', 'Refactor', 'GoToHell', 'any_old_garbade!!!21' ]:
+ with self.subTest( command = command ):
+ EmptyFixItTest( command )
- @pytest.mark.parametrize( 'command,response,chunks,selection,silent', [
- [ 'AnythingYouLike',
- BASIC_FIXIT, BASIC_FIXIT_CHUNKS, 0, False ],
- [ 'GoToEvenWorks',
- BASIC_FIXIT, BASIC_FIXIT_CHUNKS, 0, False ],
- [ 'FixItWorks',
- BASIC_FIXIT, BASIC_FIXIT_CHUNKS, 0, False ],
- [ 'and8434fd andy garbag!',
- BASIC_FIXIT, BASIC_FIXIT_CHUNKS, 0, False ],
- [ 'Format',
- BASIC_FIXIT, BASIC_FIXIT_CHUNKS, 0, True ],
- [ 'select from multiple 1',
- MULTI_FIXIT, MULTI_FIXIT_FIRST_CHUNKS, 0, False ],
- [ 'select from multiple 2',
- MULTI_FIXIT, MULTI_FIXIT_SECOND_CHUNKS, 1, False ],
- ] )
- def FixIt_Response_test( self, command, response, chunks, selection, silent ):
+ def test_FixIt_Response( self ):
# Ensures we recognise and handle fixit responses with some dummy chunk data
def FixItTest( command, response, chunks, selection, silent ):
with patch( 'ycm.vimsupport.ReplaceChunks' ) as replace_chunks:
@@ -247,15 +230,31 @@ def FixItTest( command, response, chunks, selection, silent ):
post_vim_message.assert_not_called()
- FixItTest( command, response, chunks, selection, silent )
+ for command, response, chunks, selection, silent in [
+ [ 'AnythingYouLike',
+ BASIC_FIXIT, BASIC_FIXIT_CHUNKS, 0, False ],
+ [ 'GoToEvenWorks',
+ BASIC_FIXIT, BASIC_FIXIT_CHUNKS, 0, False ],
+ [ 'FixItWorks',
+ BASIC_FIXIT, BASIC_FIXIT_CHUNKS, 0, False ],
+ [ 'and8434fd andy garbag!',
+ BASIC_FIXIT, BASIC_FIXIT_CHUNKS, 0, False ],
+ [ 'Format',
+ BASIC_FIXIT, BASIC_FIXIT_CHUNKS, 0, True ],
+ [ 'select from multiple 1',
+ MULTI_FIXIT, MULTI_FIXIT_FIRST_CHUNKS, 0, False ],
+ [ 'select from multiple 2',
+ MULTI_FIXIT, MULTI_FIXIT_SECOND_CHUNKS, 1, False ],
+ ]:
+ with self.subTest( command = command,
+ response = response,
+ chunks = chunks,
+ selection = selection,
+ silent = silent ):
+ FixItTest( command, response, chunks, selection, silent )
- @pytest.mark.parametrize( 'command,message', [
- [ '___________', 'This is a message' ],
- [ '', 'this is also a message' ],
- [ 'GetType', 'std::string' ],
- ] )
- def Message_Response_test( self, command, message ):
+ def test_Message_Response( self ):
# Ensures we correctly recognise and handle responses with a message to show
# to the user
@@ -266,15 +265,16 @@ def MessageTest( command, message ):
request.RunPostCommandActionsIfNeeded( 'rightbelow' )
post_vim_message.assert_called_with( message, warning = False )
- MessageTest( command, message )
-
-
- @pytest.mark.parametrize( 'command,info', [
+ for command, message in [
[ '___________', 'This is a message' ],
[ '', 'this is also a message' ],
- [ 'GetDoc', 'std::string\netc\netc' ],
- ] )
- def Detailed_Info_test( self, command, info ):
+ [ 'GetType', 'std::string' ],
+ ]:
+ with self.subTest( command = command, message = message ):
+ MessageTest( command, message )
+
+
+ def test_Detailed_Info( self ):
# Ensures we correctly detect and handle detailed_info responses which are
# used to display information in the preview window
@@ -285,10 +285,17 @@ def DetailedInfoTest( command, info ):
request.RunPostCommandActionsIfNeeded( 'topleft' )
write_to_preview.assert_called_with( info )
- DetailedInfoTest( command, info )
+ for command, info in [
+ [ '___________', 'This is a message' ],
+ [ '', 'this is also a message' ],
+ [ 'GetDoc', 'std::string\netc\netc' ],
+ ]:
+ with self.subTest( command = command, info = info ):
+ DetailedInfoTest( command, info )
- @pytest.mark.parametrize( 'test,command,response', [
+ def test_GoTo_Single( self ):
+ for test, command, response in [
[ GoToTest, 'AnythingYouLike', BASIC_GOTO ],
[ GoToTest, 'GoTo', BASIC_GOTO ],
[ GoToTest, 'FindAThing', BASIC_GOTO ],
@@ -296,6 +303,6 @@ def DetailedInfoTest( command, info ):
[ GoToListTest, 'AnythingYouLike', [ BASIC_GOTO ] ],
[ GoToListTest, 'GoTo', [] ],
[ GoToListTest, 'FixItGoto', [ BASIC_GOTO, BASIC_GOTO ] ],
- ] )
- def GoTo_Single_test( self, test, command, response ):
- test( command, response )
+ ]:
+ with self.subTest( test = test, command = command, response = response ):
+ test( command, response )
diff --git a/python/ycm/tests/client/completion_request_test.py b/python/ycm/tests/client/completion_request_test.py
index 7375536a32..2ff07fe4e4 100644
--- a/python/ycm/tests/client/completion_request_test.py
+++ b/python/ycm/tests/client/completion_request_test.py
@@ -17,14 +17,15 @@
import json
from hamcrest import assert_that, equal_to
-from ycm.tests.conftest import UserOptions
+from unittest import TestCase
+from ycm.tests import UserOptions
from ycm.tests.test_utils import MockVimModule
vim_mock = MockVimModule()
from ycm.client import completion_request
-class ConvertCompletionResponseToVimDatas_test:
+class ConvertCompletionResponseToVimDatasTest( TestCase ):
""" This class tests the
completion_request.ConvertCompletionResponseToVimDatas method """
@@ -44,7 +45,7 @@ def _Check( self, completion_data, expected_vim_data ):
raise
- def AllFields_test( self ):
+ def test_AllFields( self ):
extra_data = {
'doc_string': 'DOC STRING',
}
@@ -68,7 +69,7 @@ def AllFields_test( self ):
} )
- def OnlyInsertionTextField_test( self ):
+ def test_OnlyInsertionTextField( self ):
self._Check( {
'insertion_text': 'INSERTION TEXT'
}, {
@@ -84,7 +85,7 @@ def OnlyInsertionTextField_test( self ):
} )
- def JustDetailedInfo_test( self ):
+ def test_JustDetailedInfo( self ):
self._Check( {
'insertion_text': 'INSERTION TEXT',
'menu_text': 'MENU TEXT',
@@ -104,7 +105,7 @@ def JustDetailedInfo_test( self ):
} )
- def JustDocString_test( self ):
+ def test_JustDocString( self ):
extra_data = {
'doc_string': 'DOC STRING',
}
@@ -127,7 +128,7 @@ def JustDocString_test( self ):
} )
- def ExtraInfoNoDocString_test( self ):
+ def test_ExtraInfoNoDocString( self ):
self._Check( {
'insertion_text': 'INSERTION TEXT',
'menu_text': 'MENU TEXT',
@@ -148,7 +149,7 @@ def ExtraInfoNoDocString_test( self ):
} )
- def NullCharactersInExtraInfoAndDocString_test( self ):
+ def test_NullCharactersInExtraInfoAndDocString( self ):
extra_data = {
'doc_string': 'DOC\x00STRING'
}
@@ -172,7 +173,7 @@ def NullCharactersInExtraInfoAndDocString_test( self ):
} )
- def ExtraInfoNoDocStringWithDetailedInfo_test( self ):
+ def test_ExtraInfoNoDocStringWithDetailedInfo( self ):
self._Check( {
'insertion_text': 'INSERTION TEXT',
'menu_text': 'MENU TEXT',
@@ -194,7 +195,7 @@ def ExtraInfoNoDocStringWithDetailedInfo_test( self ):
} )
- def EmptyInsertionText_test( self ):
+ def test_EmptyInsertionText( self ):
extra_data = {
'doc_string': 'DOC STRING',
}
@@ -218,7 +219,7 @@ def EmptyInsertionText_test( self ):
} )
- def TruncateForPopup_test( self, *args ):
+ def test_TruncateForPopup( self, *args ):
with UserOptions( { '&columns': 60, '&completeopt': b'popup,menuone' } ):
extra_data = {
'doc_string': 'DOC STRING',
@@ -244,7 +245,7 @@ def TruncateForPopup_test( self, *args ):
} )
- def OnlyTruncateForPopupIfNecessary_test( self, *args ):
+ def test_OnlyTruncateForPopupIfNecessary( self, *args ):
with UserOptions( { '&columns': 60, '&completeopt': b'popup,menuone' } ):
extra_data = {
'doc_string': 'DOC STRING',
@@ -269,7 +270,7 @@ def OnlyTruncateForPopupIfNecessary_test( self, *args ):
} )
- def DontTruncateIfNotPopup_test( self, *args ):
+ def test_DontTruncateIfNotPopup( self, *args ):
with UserOptions( { '&columns': 60, '&completeopt': b'preview,menuone' } ):
extra_data = {
'doc_string': 'DOC STRING',
@@ -294,7 +295,7 @@ def DontTruncateIfNotPopup_test( self, *args ):
} )
- def TruncateForPopupWithoutDuplication_test( self, *args ):
+ def test_TruncateForPopupWithoutDuplication( self, *args ):
with UserOptions( { '&columns': 60, '&completeopt': b'popup,menuone' } ):
extra_data = {
'doc_string': 'DOC STRING',
diff --git a/python/ycm/tests/client/debug_info_request_test.py b/python/ycm/tests/client/debug_info_request_test.py
index 93f7ac393b..9c3aa7b8e0 100644
--- a/python/ycm/tests/client/debug_info_request_test.py
+++ b/python/ycm/tests/client/debug_info_request_test.py
@@ -17,6 +17,7 @@
from copy import deepcopy
from hamcrest import assert_that, contains_string, equal_to
+from unittest import TestCase
from ycm.client.debug_info_request import FormatDebugInfoResponse
@@ -66,111 +67,113 @@
}
-def FormatDebugInfoResponse_NoResponse_test():
- assert_that(
- FormatDebugInfoResponse( None ),
- equal_to( 'Server errored, no debug info from server\n' )
- )
+class DebugInfoRequestTest( TestCase ):
+ def test_FormatDebugInfoResponse_NoResponse( self ):
+ assert_that(
+ FormatDebugInfoResponse( None ),
+ equal_to( 'Server errored, no debug info from server\n' )
+ )
-def FormatDebugInfoResponse_NoExtraConf_test():
- response = deepcopy( GENERIC_RESPONSE )
- response[ 'extra_conf' ].update( {
- 'is_loaded': False,
- 'path': None
- } )
- assert_that(
- FormatDebugInfoResponse( response ),
- contains_string(
- 'No extra configuration file found\n'
+ def test_FormatDebugInfoResponse_NoExtraConf( self ):
+ response = deepcopy( GENERIC_RESPONSE )
+ response[ 'extra_conf' ].update( {
+ 'is_loaded': False,
+ 'path': None
+ } )
+ assert_that(
+ FormatDebugInfoResponse( response ),
+ contains_string(
+ 'No extra configuration file found\n'
+ )
)
- )
-def FormatDebugInfoResponse_ExtraConfFoundButNotLoaded_test():
- response = deepcopy( GENERIC_RESPONSE )
- response[ 'extra_conf' ].update( {
- 'is_loaded': False,
- 'path': '/path/to/extra/conf'
- } )
- assert_that(
- FormatDebugInfoResponse( response ),
- contains_string(
- 'Extra configuration file found but not loaded\n'
- 'Extra configuration path: /path/to/extra/conf\n'
+ def test_FormatDebugInfoResponse_ExtraConfFoundButNotLoaded( self ):
+ response = deepcopy( GENERIC_RESPONSE )
+ response[ 'extra_conf' ].update( {
+ 'is_loaded': False,
+ 'path': '/path/to/extra/conf'
+ } )
+ assert_that(
+ FormatDebugInfoResponse( response ),
+ contains_string(
+ 'Extra configuration file found but not loaded\n'
+ 'Extra configuration path: /path/to/extra/conf\n'
+ )
)
- )
-def FormatDebugInfoResponse_ExtraConfFoundAndLoaded_test():
- response = deepcopy( GENERIC_RESPONSE )
- response[ 'extra_conf' ].update( {
- 'is_loaded': True,
- 'path': '/path/to/extra/conf'
- } )
- assert_that(
- FormatDebugInfoResponse( response ),
- contains_string(
- 'Extra configuration file found and loaded\n'
- 'Extra configuration path: /path/to/extra/conf\n'
+ def test_FormatDebugInfoResponse_ExtraConfFoundAndLoaded( self ):
+ response = deepcopy( GENERIC_RESPONSE )
+ response[ 'extra_conf' ].update( {
+ 'is_loaded': True,
+ 'path': '/path/to/extra/conf'
+ } )
+ assert_that(
+ FormatDebugInfoResponse( response ),
+ contains_string(
+ 'Extra configuration file found and loaded\n'
+ 'Extra configuration path: /path/to/extra/conf\n'
+ )
)
- )
-
-
-def FormatDebugInfoResponse_Completer_ServerRunningWithHost_test():
- response = deepcopy( GENERIC_RESPONSE )
- assert_that(
- FormatDebugInfoResponse( response ),
- contains_string(
- 'Completer name completer debug information:\n'
- ' Server name running at: http://127.0.0.1:1234\n'
- ' Server name process ID: 12345\n'
- ' Server name executable: /path/to/executable\n'
- ' Server name logfiles:\n'
- ' /path/to/stdout/logfile\n'
- ' /path/to/stderr/logfile\n'
- ' Server name key: value\n'
- ' Key: value\n'
+
+
+ def test_FormatDebugInfoResponse_Completer_ServerRunningWithHost( self ):
+ response = deepcopy( GENERIC_RESPONSE )
+ assert_that(
+ FormatDebugInfoResponse( response ),
+ contains_string(
+ 'Completer name completer debug information:\n'
+ ' Server name running at: http://127.0.0.1:1234\n'
+ ' Server name process ID: 12345\n'
+ ' Server name executable: /path/to/executable\n'
+ ' Server name logfiles:\n'
+ ' /path/to/stdout/logfile\n'
+ ' /path/to/stderr/logfile\n'
+ ' Server name key: value\n'
+ ' Key: value\n'
+ )
)
- )
-
-
-def FormatDebugInfoResponse_Completer_ServerRunningWithoutHost_test():
- response = deepcopy( GENERIC_RESPONSE )
- response[ 'completer' ][ 'servers' ][ 0 ].update( {
- 'address': None,
- 'port': None
- } )
- assert_that(
- FormatDebugInfoResponse( response ),
- contains_string(
- 'Completer name completer debug information:\n'
- ' Server name running\n'
- ' Server name process ID: 12345\n'
- ' Server name executable: /path/to/executable\n'
- ' Server name logfiles:\n'
- ' /path/to/stdout/logfile\n'
- ' /path/to/stderr/logfile\n'
- ' Server name key: value\n'
- ' Key: value\n'
+
+
+ def test_FormatDebugInfoResponse_Completer_ServerRunningWithoutHost( self ):
+ response = deepcopy( GENERIC_RESPONSE )
+ response[ 'completer' ][ 'servers' ][ 0 ].update( {
+ 'address': None,
+ 'port': None
+ } )
+ assert_that(
+ FormatDebugInfoResponse( response ),
+ contains_string(
+ 'Completer name completer debug information:\n'
+ ' Server name running\n'
+ ' Server name process ID: 12345\n'
+ ' Server name executable: /path/to/executable\n'
+ ' Server name logfiles:\n'
+ ' /path/to/stdout/logfile\n'
+ ' /path/to/stderr/logfile\n'
+ ' Server name key: value\n'
+ ' Key: value\n'
+ )
)
- )
-
-
-def FormatDebugInfoResponse_Completer_ServerNotRunningWithNoLogfiles_test():
- response = deepcopy( GENERIC_RESPONSE )
- response[ 'completer' ][ 'servers' ][ 0 ].update( {
- 'is_running': False,
- 'logfiles': []
- } )
- assert_that(
- FormatDebugInfoResponse( response ),
- contains_string(
- 'Completer name completer debug information:\n'
- ' Server name not running\n'
- ' Server name executable: /path/to/executable\n'
- ' No logfiles available\n'
- ' Server name key: value\n'
- ' Key: value\n'
+
+
+ def test_FormatDebugInfoResponse_Completer_ServerNotRunningWithNoLogfiles(
+ self ):
+ response = deepcopy( GENERIC_RESPONSE )
+ response[ 'completer' ][ 'servers' ][ 0 ].update( {
+ 'is_running': False,
+ 'logfiles': []
+ } )
+ assert_that(
+ FormatDebugInfoResponse( response ),
+ contains_string(
+ 'Completer name completer debug information:\n'
+ ' Server name not running\n'
+ ' Server name executable: /path/to/executable\n'
+ ' No logfiles available\n'
+ ' Server name key: value\n'
+ ' Key: value\n'
+ )
)
- )
diff --git a/python/ycm/tests/client/messages_request_test.py b/python/ycm/tests/client/messages_request_test.py
index aa5931deb2..1e1a10e900 100644
--- a/python/ycm/tests/client/messages_request_test.py
+++ b/python/ycm/tests/client/messages_request_test.py
@@ -19,116 +19,122 @@
MockVimModule()
from hamcrest import assert_that, equal_to
+from unittest import TestCase
from unittest.mock import patch, call
from ycm.client.messages_request import _HandlePollResponse
from ycm.tests.test_utils import ExtendedMock
-def HandlePollResponse_NoMessages_test():
- assert_that( _HandlePollResponse( True, None ), equal_to( True ) )
-
- # Other non-False responses mean the same thing
- assert_that( _HandlePollResponse( '', None ), equal_to( True ) )
- assert_that( _HandlePollResponse( 1, None ), equal_to( True ) )
- assert_that( _HandlePollResponse( {}, None ), equal_to( True ) )
-
-
-def HandlePollResponse_PollingNotSupported_test():
- assert_that( _HandlePollResponse( False, None ), equal_to( False ) )
-
- # 0 is not False
- assert_that( _HandlePollResponse( 0, None ), equal_to( True ) )
-
-
-@patch( 'ycm.client.messages_request.PostVimMessage',
- new_callable = ExtendedMock )
-def HandlePollResponse_SingleMessage_test( post_vim_message ):
- assert_that( _HandlePollResponse( [ { 'message': 'this is a message' } ] ,
- None ),
- equal_to( True ) )
-
- post_vim_message.assert_has_exact_calls( [
- call( 'this is a message', warning=False, truncate=True )
- ] )
-
-
-@patch( 'ycm.client.messages_request.PostVimMessage',
- new_callable = ExtendedMock )
-def HandlePollResponse_MultipleMessages_test( post_vim_message ):
- assert_that( _HandlePollResponse( [ { 'message': 'this is a message' },
- { 'message': 'this is another one' } ] ,
- None ),
- equal_to( True ) )
-
- post_vim_message.assert_has_exact_calls( [
- call( 'this is a message', warning=False, truncate=True ),
- call( 'this is another one', warning=False, truncate=True )
- ] )
-
-
-def HandlePollResponse_SingleDiagnostic_test():
- diagnostics_handler = ExtendedMock()
- messages = [
- { 'filepath': 'foo', 'diagnostics': [ 'PLACEHOLDER' ] },
- ]
- assert_that( _HandlePollResponse( messages, diagnostics_handler ),
- equal_to( True ) )
- diagnostics_handler.UpdateWithNewDiagnosticsForFile.assert_has_exact_calls( [
- call( 'foo', [ 'PLACEHOLDER' ] )
- ] )
-
-
-def HandlePollResponse_MultipleDiagnostics_test():
- diagnostics_handler = ExtendedMock()
- messages = [
- { 'filepath': 'foo', 'diagnostics': [ 'PLACEHOLDER1' ] },
- { 'filepath': 'bar', 'diagnostics': [ 'PLACEHOLDER2' ] },
- { 'filepath': 'baz', 'diagnostics': [ 'PLACEHOLDER3' ] },
- { 'filepath': 'foo', 'diagnostics': [ 'PLACEHOLDER4' ] },
- ]
- assert_that( _HandlePollResponse( messages, diagnostics_handler ),
- equal_to( True ) )
- diagnostics_handler.UpdateWithNewDiagnosticsForFile.assert_has_exact_calls( [
- call( 'foo', [ 'PLACEHOLDER1' ] ),
- call( 'bar', [ 'PLACEHOLDER2' ] ),
- call( 'baz', [ 'PLACEHOLDER3' ] ),
- call( 'foo', [ 'PLACEHOLDER4' ] )
- ] )
-
-
-@patch( 'ycm.client.messages_request.PostVimMessage',
- new_callable = ExtendedMock )
-def HandlePollResponse_MultipleMessagesAndDiagnostics_test( post_vim_message ):
- diagnostics_handler = ExtendedMock()
- messages = [
- { 'filepath': 'foo', 'diagnostics': [ 'PLACEHOLDER1' ] },
- { 'message': 'On the first day of Christmas, my VimScript gave to me' },
- { 'filepath': 'bar', 'diagnostics': [ 'PLACEHOLDER2' ] },
- { 'message': 'A test file in a Command-T' },
- { 'filepath': 'baz', 'diagnostics': [ 'PLACEHOLDER3' ] },
- { 'message': 'On the second day of Christmas, my VimScript gave to me' },
- { 'filepath': 'foo', 'diagnostics': [ 'PLACEHOLDER4' ] },
- { 'message': 'Two popup menus, and a test file in a Command-T' },
- ]
- assert_that( _HandlePollResponse( messages, diagnostics_handler ),
- equal_to( True ) )
- diagnostics_handler.UpdateWithNewDiagnosticsForFile.assert_has_exact_calls( [
- call( 'foo', [ 'PLACEHOLDER1' ] ),
- call( 'bar', [ 'PLACEHOLDER2' ] ),
- call( 'baz', [ 'PLACEHOLDER3' ] ),
- call( 'foo', [ 'PLACEHOLDER4' ] )
- ] )
-
- post_vim_message.assert_has_exact_calls( [
- call( 'On the first day of Christmas, my VimScript gave to me',
- warning=False,
- truncate=True ),
- call( 'A test file in a Command-T', warning=False, truncate=True ),
- call( 'On the second day of Christmas, my VimScript gave to me',
- warning=False,
- truncate=True ),
- call( 'Two popup menus, and a test file in a Command-T',
- warning=False,
- truncate=True ),
- ] )
+class MessagesRequestTest( TestCase ):
+ def test_HandlePollResponse_NoMessages( self ):
+ assert_that( _HandlePollResponse( True, None ), equal_to( True ) )
+
+ # Other non-False responses mean the same thing
+ assert_that( _HandlePollResponse( '', None ), equal_to( True ) )
+ assert_that( _HandlePollResponse( 1, None ), equal_to( True ) )
+ assert_that( _HandlePollResponse( {}, None ), equal_to( True ) )
+
+
+ def test_HandlePollResponse_PollingNotSupported( self ):
+ assert_that( _HandlePollResponse( False, None ), equal_to( False ) )
+
+ # 0 is not False
+ assert_that( _HandlePollResponse( 0, None ), equal_to( True ) )
+
+
+ @patch( 'ycm.client.messages_request.PostVimMessage',
+ new_callable = ExtendedMock )
+ def test_HandlePollResponse_SingleMessage( self, post_vim_message ):
+ assert_that( _HandlePollResponse( [ { 'message': 'this is a message' } ] ,
+ None ),
+ equal_to( True ) )
+
+ post_vim_message.assert_has_exact_calls( [
+ call( 'this is a message', warning=False, truncate=True )
+ ] )
+
+
+ @patch( 'ycm.client.messages_request.PostVimMessage',
+ new_callable = ExtendedMock )
+ def test_HandlePollResponse_MultipleMessages( self, post_vim_message ):
+ assert_that( _HandlePollResponse( [ { 'message': 'this is a message' },
+ { 'message': 'this is another one' } ] ,
+ None ),
+ equal_to( True ) )
+
+ post_vim_message.assert_has_exact_calls( [
+ call( 'this is a message', warning=False, truncate=True ),
+ call( 'this is another one', warning=False, truncate=True )
+ ] )
+
+
+ def test_HandlePollResponse_SingleDiagnostic( self ):
+ diagnostics_handler = ExtendedMock()
+ messages = [
+ { 'filepath': 'foo', 'diagnostics': [ 'PLACEHOLDER' ] },
+ ]
+ assert_that( _HandlePollResponse( messages, diagnostics_handler ),
+ equal_to( True ) )
+ diagnostics_handler.UpdateWithNewDiagnosticsForFile.assert_has_exact_calls(
+ [
+ call( 'foo', [ 'PLACEHOLDER' ] )
+ ] )
+
+
+ def test_HandlePollResponse_MultipleDiagnostics( self ):
+ diagnostics_handler = ExtendedMock()
+ messages = [
+ { 'filepath': 'foo', 'diagnostics': [ 'PLACEHOLDER1' ] },
+ { 'filepath': 'bar', 'diagnostics': [ 'PLACEHOLDER2' ] },
+ { 'filepath': 'baz', 'diagnostics': [ 'PLACEHOLDER3' ] },
+ { 'filepath': 'foo', 'diagnostics': [ 'PLACEHOLDER4' ] },
+ ]
+ assert_that( _HandlePollResponse( messages, diagnostics_handler ),
+ equal_to( True ) )
+ diagnostics_handler.UpdateWithNewDiagnosticsForFile.assert_has_exact_calls(
+ [
+ call( 'foo', [ 'PLACEHOLDER1' ] ),
+ call( 'bar', [ 'PLACEHOLDER2' ] ),
+ call( 'baz', [ 'PLACEHOLDER3' ] ),
+ call( 'foo', [ 'PLACEHOLDER4' ] )
+ ] )
+
+
+ @patch( 'ycm.client.messages_request.PostVimMessage',
+ new_callable = ExtendedMock )
+ def test_HandlePollResponse_MultipleMessagesAndDiagnostics(
+ self, post_vim_message ):
+ diagnostics_handler = ExtendedMock()
+ messages = [
+ { 'filepath': 'foo', 'diagnostics': [ 'PLACEHOLDER1' ] },
+ { 'message': 'On the first day of Christmas, my VimScript gave to me' },
+ { 'filepath': 'bar', 'diagnostics': [ 'PLACEHOLDER2' ] },
+ { 'message': 'A test file in a Command-T' },
+ { 'filepath': 'baz', 'diagnostics': [ 'PLACEHOLDER3' ] },
+ { 'message': 'On the second day of Christmas, my VimScript gave to me' },
+ { 'filepath': 'foo', 'diagnostics': [ 'PLACEHOLDER4' ] },
+ { 'message': 'Two popup menus, and a test file in a Command-T' },
+ ]
+ assert_that( _HandlePollResponse( messages, diagnostics_handler ),
+ equal_to( True ) )
+ diagnostics_handler.UpdateWithNewDiagnosticsForFile.assert_has_exact_calls(
+ [
+ call( 'foo', [ 'PLACEHOLDER1' ] ),
+ call( 'bar', [ 'PLACEHOLDER2' ] ),
+ call( 'baz', [ 'PLACEHOLDER3' ] ),
+ call( 'foo', [ 'PLACEHOLDER4' ] )
+ ] )
+
+ post_vim_message.assert_has_exact_calls( [
+ call( 'On the first day of Christmas, my VimScript gave to me',
+ warning=False,
+ truncate=True ),
+ call( 'A test file in a Command-T', warning=False, truncate=True ),
+ call( 'On the second day of Christmas, my VimScript gave to me',
+ warning=False,
+ truncate=True ),
+ call( 'Two popup menus, and a test file in a Command-T',
+ warning=False,
+ truncate=True ),
+ ] )
diff --git a/python/ycm/tests/client/omni_completion_request_test.py b/python/ycm/tests/client/omni_completion_request_test.py
index b9f611ab90..a78f2da6ae 100644
--- a/python/ycm/tests/client/omni_completion_request_test.py
+++ b/python/ycm/tests/client/omni_completion_request_test.py
@@ -15,6 +15,7 @@
# You should have received a copy of the GNU General Public License
# along with YouCompleteMe. If not, see .
+from unittest import TestCase
from unittest.mock import MagicMock
from hamcrest import assert_that, has_entries
@@ -36,19 +37,20 @@ def BuildOmnicompletionRequest( results, start_column = 1 ):
return request
-def Done_AlwaysTrue_test():
- request = BuildOmnicompletionRequest( [] )
+class OmniCompletionRequestTest( TestCase ):
+ def test_Done_AlwaysTrue( self ):
+ request = BuildOmnicompletionRequest( [] )
- assert_that( request.Done() )
+ assert_that( request.Done() )
-def Response_FromOmniCompleter_test():
- results = [ { "word": "test" } ]
- request = BuildOmnicompletionRequest( results )
+ def test_Response_FromOmniCompleter( self ):
+ results = [ { "word": "test" } ]
+ request = BuildOmnicompletionRequest( results )
- assert_that( request.Response(), has_entries( {
- 'line': 1,
- 'column': 1,
- 'completion_start_column': 1,
- 'completions': results
- } ) )
+ assert_that( request.Response(), has_entries( {
+ 'line': 1,
+ 'column': 1,
+ 'completion_start_column': 1,
+ 'completions': results
+ } ) )
diff --git a/python/ycm/tests/command_test.py b/python/ycm/tests/command_test.py
index fbb9d4644d..b938e94e6c 100644
--- a/python/ycm/tests/command_test.py
+++ b/python/ycm/tests/command_test.py
@@ -20,142 +20,145 @@
from hamcrest import assert_that, contains_exactly, has_entries
from unittest.mock import patch
+from unittest import TestCase
from ycm.tests import YouCompleteMeInstance
-@YouCompleteMeInstance( { 'g:ycm_extra_conf_vim_data': [ 'tempname()' ] } )
-def SendCommandRequest_ExtraConfVimData_Works_test( ycm ):
- current_buffer = VimBuffer( 'buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
- ycm.SendCommandRequest( [ 'GoTo' ], 'aboveleft', False, 1, 1 )
- assert_that(
- # Positional arguments passed to SendCommandRequest.
- send_request.call_args[ 0 ],
- contains_exactly(
- contains_exactly( 'GoTo' ),
- 'aboveleft',
- 'same-buffer',
- has_entries( {
- 'options': has_entries( {
- 'tab_size': 2,
- 'insert_spaces': True,
- } ),
- 'extra_conf_data': has_entries( {
- 'tempname()': '_TEMP_FILE_'
- } ),
- } )
+class CommandTest( TestCase ):
+ @YouCompleteMeInstance( { 'g:ycm_extra_conf_vim_data': [ 'tempname()' ] } )
+ def test_SendCommandRequest_ExtraConfVimData_Works( self, ycm ):
+ current_buffer = VimBuffer( 'buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
+ ycm.SendCommandRequest( [ 'GoTo' ], 'aboveleft', False, 1, 1 )
+ assert_that(
+ # Positional arguments passed to SendCommandRequest.
+ send_request.call_args[ 0 ],
+ contains_exactly(
+ contains_exactly( 'GoTo' ),
+ 'aboveleft',
+ 'same-buffer',
+ has_entries( {
+ 'options': has_entries( {
+ 'tab_size': 2,
+ 'insert_spaces': True,
+ } ),
+ 'extra_conf_data': has_entries( {
+ 'tempname()': '_TEMP_FILE_'
+ } ),
+ } )
+ )
+ )
+
+
+ @YouCompleteMeInstance( {
+ 'g:ycm_extra_conf_vim_data': [ 'undefined_value' ] } )
+ def test_SendCommandRequest_ExtraConfData_UndefinedValue( self, ycm ):
+ current_buffer = VimBuffer( 'buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
+ ycm.SendCommandRequest( [ 'GoTo' ], 'belowright', False, 1, 1 )
+ assert_that(
+ # Positional arguments passed to SendCommandRequest.
+ send_request.call_args[ 0 ],
+ contains_exactly(
+ contains_exactly( 'GoTo' ),
+ 'belowright',
+ 'same-buffer',
+ has_entries( {
+ 'options': has_entries( {
+ 'tab_size': 2,
+ 'insert_spaces': True,
+ } )
+ } )
+ )
)
- )
-@YouCompleteMeInstance( { 'g:ycm_extra_conf_vim_data': [ 'undefined_value' ] } )
-def SendCommandRequest_ExtraConfData_UndefinedValue_test( ycm ):
- current_buffer = VimBuffer( 'buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
- ycm.SendCommandRequest( [ 'GoTo' ], 'belowright', False, 1, 1 )
- assert_that(
- # Positional arguments passed to SendCommandRequest.
- send_request.call_args[ 0 ],
- contains_exactly(
- contains_exactly( 'GoTo' ),
- 'belowright',
+ @YouCompleteMeInstance()
+ def test_SendCommandRequest_BuildRange_NoVisualMarks( self, ycm, *args ):
+ current_buffer = VimBuffer( 'buffer', contents = [ 'first line',
+ 'second line' ] )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
+ ycm.SendCommandRequest( [ 'GoTo' ], '', True, 1, 2 )
+ send_request.assert_called_once_with(
+ [ 'GoTo' ],
+ '',
'same-buffer',
- has_entries( {
- 'options': has_entries( {
+ {
+ 'options': {
'tab_size': 2,
- 'insert_spaces': True,
- } )
- } )
+ 'insert_spaces': True
+ },
+ 'range': {
+ 'start': {
+ 'line_num': 1,
+ 'column_num': 1
+ },
+ 'end': {
+ 'line_num': 2,
+ 'column_num': 12
+ }
+ }
+ }
)
- )
-@YouCompleteMeInstance()
-def SendCommandRequest_BuildRange_NoVisualMarks_test( ycm, *args ):
- current_buffer = VimBuffer( 'buffer', contents = [ 'first line',
- 'second line' ] )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
- ycm.SendCommandRequest( [ 'GoTo' ], '', True, 1, 2 )
- send_request.assert_called_once_with(
- [ 'GoTo' ],
- '',
- 'same-buffer',
- {
- 'options': {
- 'tab_size': 2,
- 'insert_spaces': True
- },
- 'range': {
- 'start': {
- 'line_num': 1,
- 'column_num': 1
+ @YouCompleteMeInstance()
+ def test_SendCommandRequest_BuildRange_VisualMarks( self, ycm, *args ):
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'first line',
+ 'second line' ],
+ visual_start = [ 1, 4 ],
+ visual_end = [ 2, 8 ] )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
+ ycm.SendCommandRequest( [ 'GoTo' ], 'tab', True, 1, 2 )
+ send_request.assert_called_once_with(
+ [ 'GoTo' ],
+ 'tab',
+ 'same-buffer',
+ {
+ 'options': {
+ 'tab_size': 2,
+ 'insert_spaces': True
},
- 'end': {
- 'line_num': 2,
- 'column_num': 12
+ 'range': {
+ 'start': {
+ 'line_num': 1,
+ 'column_num': 5
+ },
+ 'end': {
+ 'line_num': 2,
+ 'column_num': 9
+ }
}
}
- }
- )
+ )
-@YouCompleteMeInstance()
-def SendCommandRequest_BuildRange_VisualMarks_test( ycm, *args ):
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'first line',
- 'second line' ],
- visual_start = [ 1, 4 ],
- visual_end = [ 2, 8 ] )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
- ycm.SendCommandRequest( [ 'GoTo' ], 'tab', True, 1, 2 )
- send_request.assert_called_once_with(
+ @YouCompleteMeInstance()
+ def test_SendCommandRequest_IgnoreFileTypeOption( self, ycm, *args ):
+ current_buffer = VimBuffer( 'buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ expected_args = (
[ 'GoTo' ],
- 'tab',
+ '',
'same-buffer',
{
'options': {
'tab_size': 2,
'insert_spaces': True
},
- 'range': {
- 'start': {
- 'line_num': 1,
- 'column_num': 5
- },
- 'end': {
- 'line_num': 2,
- 'column_num': 9
- }
- }
}
)
+ with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
+ ycm.SendCommandRequest( [ 'ft=ycm:ident', 'GoTo' ], '', False, 1, 1 )
+ send_request.assert_called_once_with( *expected_args )
-@YouCompleteMeInstance()
-def SendCommandRequest_IgnoreFileTypeOption_test( ycm, *args ):
- current_buffer = VimBuffer( 'buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- expected_args = (
- [ 'GoTo' ],
- '',
- 'same-buffer',
- {
- 'options': {
- 'tab_size': 2,
- 'insert_spaces': True
- },
- }
- )
-
- with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
- ycm.SendCommandRequest( [ 'ft=ycm:ident', 'GoTo' ], '', False, 1, 1 )
- send_request.assert_called_once_with( *expected_args )
-
- with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
- ycm.SendCommandRequest( [ 'GoTo', 'ft=python' ], '', False, 1, 1 )
- send_request.assert_called_once_with( *expected_args )
+ with patch( 'ycm.youcompleteme.SendCommandRequest' ) as send_request:
+ ycm.SendCommandRequest( [ 'GoTo', 'ft=python' ], '', False, 1, 1 )
+ send_request.assert_called_once_with( *expected_args )
diff --git a/python/ycm/tests/completion_test.py b/python/ycm/tests/completion_test.py
index 8e45bea398..b5c0565932 100644
--- a/python/ycm/tests/completion_test.py
+++ b/python/ycm/tests/completion_test.py
@@ -25,6 +25,7 @@
empty,
equal_to,
has_entries )
+from unittest import TestCase
from unittest.mock import call, MagicMock, patch
from ycm.tests import PathToTestFile, YouCompleteMeInstance
@@ -68,410 +69,416 @@ def MockResolveRequest( response_method ):
yield
-@YouCompleteMeInstance()
-def SendCompletionRequest_UnicodeWorkingDirectory_test( ycm ):
- unicode_dir = PathToTestFile( 'uni¢od€' )
- current_buffer = VimBuffer( PathToTestFile( 'uni¢𐍈d€', 'current_buffer' ) )
+class CompletionTest( TestCase ):
+ @YouCompleteMeInstance()
+ def test_SendCompletionRequest_UnicodeWorkingDirectory( self, ycm ):
+ unicode_dir = PathToTestFile( 'uni¢od€' )
+ current_buffer = VimBuffer( PathToTestFile( 'uni¢𐍈d€', 'current_buffer' ) )
+
+ def ServerResponse( *args ):
+ return { 'completions': [], 'completion_start_column': 1 }
+
+ with CurrentWorkingDirectory( unicode_dir ):
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with MockCompletionRequest( ServerResponse ):
+ ycm.SendCompletionRequest()
+ assert_that( ycm.CompletionRequestReady() )
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': empty(),
+ 'completion_start_column': 1
+ } )
+ )
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_SendCompletionRequest_ResponseContainingError(
+ self, ycm, post_vim_message ):
+ current_buffer = VimBuffer( 'buffer' )
+
+ def ServerResponse( *args ):
+ return {
+ 'completions': [ {
+ 'insertion_text': 'insertion_text',
+ 'menu_text': 'menu_text',
+ 'extra_menu_info': 'extra_menu_info',
+ 'detailed_info': 'detailed_info',
+ 'kind': 'kind',
+ 'extra_data': {
+ 'doc_string': 'doc_string'
+ }
+ } ],
+ 'completion_start_column': 3,
+ 'errors': [ {
+ 'exception': {
+ 'TYPE': 'Exception'
+ },
+ 'message': 'message',
+ 'traceback': 'traceback'
+ } ]
+ }
- def ServerResponse( *args ):
- return { 'completions': [], 'completion_start_column': 1 }
-
- with CurrentWorkingDirectory( unicode_dir ):
with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
with MockCompletionRequest( ServerResponse ):
ycm.SendCompletionRequest()
assert_that( ycm.CompletionRequestReady() )
+ response = ycm.GetCompletionResponse()
+ post_vim_message.assert_has_exact_calls( [
+ call( 'Exception: message', truncate = True )
+ ] )
assert_that(
- ycm.GetCompletionResponse(),
+ response,
+ has_entries( {
+ 'completions': contains_exactly( has_entries( {
+ 'word': 'insertion_text',
+ 'abbr': 'menu_text',
+ 'menu': 'extra_menu_info',
+ 'info': 'detailed_info\ndoc_string',
+ 'kind': 'k',
+ 'dup': 1,
+ 'empty': 1
+ } ) ),
+ 'completion_start_column': 3
+ } )
+ )
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.client.base_request._logger', autospec = True )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_SendCompletionRequest_ErrorFromServer( self,
+ ycm,
+ post_vim_message,
+ logger ):
+ current_buffer = VimBuffer( 'buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with MockCompletionRequest( ServerError( 'Server error' ) ):
+ ycm.SendCompletionRequest()
+ assert_that( ycm.CompletionRequestReady() )
+ response = ycm.GetCompletionResponse()
+ logger.exception.assert_called_with( 'Error while handling server '
+ 'response' )
+ post_vim_message.assert_has_exact_calls( [
+ call( 'Server error', truncate = True )
+ ] )
+ assert_that(
+ response,
has_entries( {
'completions': empty(),
- 'completion_start_column': 1
+ 'completion_start_column': -1
} )
)
-@YouCompleteMeInstance()
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def SendCompletionRequest_ResponseContainingError_test( post_vim_message, ycm ):
- current_buffer = VimBuffer( 'buffer' )
-
- def ServerResponse( *args ):
- return {
- 'completions': [ {
- 'insertion_text': 'insertion_text',
- 'menu_text': 'menu_text',
- 'extra_menu_info': 'extra_menu_info',
- 'detailed_info': 'detailed_info',
- 'kind': 'kind',
- 'extra_data': {
- 'doc_string': 'doc_string'
- }
- } ],
- 'completion_start_column': 3,
- 'errors': [ {
- 'exception': {
- 'TYPE': 'Exception'
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.client.base_request._logger', autospec = True )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_ResolveCompletionRequest_Resolves( self,
+ ycm,
+ post_vim_message,
+ logger ):
+
+ def CompletionResponse( *args ):
+ return {
+ 'completions': [ {
+ 'insertion_text': 'insertion_text',
+ 'menu_text': 'menu_text',
+ 'extra_menu_info': 'extra_menu_info',
+ 'detailed_info': 'detailed_info',
+ 'kind': 'kind',
+ 'extra_data': {
+ 'doc_string': 'doc_string',
+ 'resolve': 10
+ }
+ } ],
+ 'completion_start_column': 3,
+ 'errors': []
+ }
+
+ def ResolveResponse( *args ):
+ return {
+ 'completion': {
+ 'insertion_text': 'insertion_text',
+ 'menu_text': 'menu_text',
+ 'extra_menu_info': 'extra_menu_info',
+ 'detailed_info': 'detailed_info',
+ 'kind': 'kind',
+ 'extra_data': {
+ 'doc_string': 'doc_string with more info'
+ }
},
- 'message': 'message',
- 'traceback': 'traceback'
- } ]
- }
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with MockCompletionRequest( ServerResponse ):
- ycm.SendCompletionRequest()
- assert_that( ycm.CompletionRequestReady() )
- response = ycm.GetCompletionResponse()
- post_vim_message.assert_has_exact_calls( [
- call( 'Exception: message', truncate = True )
- ] )
- assert_that(
- response,
- has_entries( {
- 'completions': contains_exactly( has_entries( {
- 'word': 'insertion_text',
- 'abbr': 'menu_text',
- 'menu': 'extra_menu_info',
- 'info': 'detailed_info\ndoc_string',
- 'kind': 'k',
- 'dup': 1,
- 'empty': 1
- } ) ),
- 'completion_start_column': 3
- } )
- )
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.client.base_request._logger', autospec = True )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def SendCompletionRequest_ErrorFromServer_test( post_vim_message,
- logger,
- ycm ):
- current_buffer = VimBuffer( 'buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with MockCompletionRequest( ServerError( 'Server error' ) ):
- ycm.SendCompletionRequest()
- assert_that( ycm.CompletionRequestReady() )
- response = ycm.GetCompletionResponse()
- logger.exception.assert_called_with( 'Error while handling server '
- 'response' )
- post_vim_message.assert_has_exact_calls( [
- call( 'Server error', truncate = True )
- ] )
- assert_that(
- response,
- has_entries( {
- 'completions': empty(),
- 'completion_start_column': -1
- } )
- )
-
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.client.base_request._logger', autospec = True )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def ResolveCompletionRequest_Resolves_test( post_vim_message,
- logger,
- ycm ):
-
- def CompletionResponse( *args ):
- return {
- 'completions': [ {
- 'insertion_text': 'insertion_text',
- 'menu_text': 'menu_text',
- 'extra_menu_info': 'extra_menu_info',
- 'detailed_info': 'detailed_info',
- 'kind': 'kind',
- 'extra_data': {
- 'doc_string': 'doc_string',
- 'resolve': 10
- }
- } ],
- 'completion_start_column': 3,
- 'errors': []
- }
-
- def ResolveResponse( *args ):
- return {
- 'completion': {
- 'insertion_text': 'insertion_text',
- 'menu_text': 'menu_text',
- 'extra_menu_info': 'extra_menu_info',
- 'detailed_info': 'detailed_info',
- 'kind': 'kind',
- 'extra_data': {
- 'doc_string': 'doc_string with more info'
- }
- },
- 'errors': []
- }
-
- current_buffer = VimBuffer( 'buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with MockCompletionRequest( CompletionResponse ):
- ycm.SendCompletionRequest()
- assert_that( ycm.CompletionRequestReady() )
- response = ycm.GetCompletionResponse()
-
- post_vim_message.assert_not_called()
- assert_that(
- response,
- has_entries( {
- 'completions': contains_exactly( has_entries( {
- 'word': 'insertion_text',
- 'abbr': 'menu_text',
- 'menu': 'extra_menu_info',
- 'info': 'detailed_info\ndoc_string',
- 'kind': 'k',
- 'dup': 1,
- 'empty': 1
- } ) ),
- 'completion_start_column': 3
- } )
- )
-
- item = response[ 'completions' ][ 0 ]
- assert_that( json.loads( item[ 'user_data' ] ),
- has_entries( { 'resolve': 10 } ) )
-
- with MockResolveRequest( ResolveResponse ):
- assert_that( ycm.ResolveCompletionItem( item ), equal_to( True ) )
- assert_that( ycm.CompletionRequestReady() )
- response = ycm.GetCompletionResponse()
- post_vim_message.assert_not_called()
-
- assert_that(
- response,
- has_entries( {
- 'completion': has_entries( {
- 'word': 'insertion_text',
- 'abbr': 'menu_text',
- 'menu': 'extra_menu_info',
- 'info': 'detailed_info\ndoc_string with more info',
- 'kind': 'k',
- 'dup': 1,
- 'empty': 1
+ 'errors': []
+ }
+
+ current_buffer = VimBuffer( 'buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with MockCompletionRequest( CompletionResponse ):
+ ycm.SendCompletionRequest()
+ assert_that( ycm.CompletionRequestReady() )
+ response = ycm.GetCompletionResponse()
+
+ post_vim_message.assert_not_called()
+ assert_that(
+ response,
+ has_entries( {
+ 'completions': contains_exactly( has_entries( {
+ 'word': 'insertion_text',
+ 'abbr': 'menu_text',
+ 'menu': 'extra_menu_info',
+ 'info': 'detailed_info\ndoc_string',
+ 'kind': 'k',
+ 'dup': 1,
+ 'empty': 1
+ } ) ),
+ 'completion_start_column': 3
+ } )
+ )
+
+ item = response[ 'completions' ][ 0 ]
+ assert_that( json.loads( item[ 'user_data' ] ),
+ has_entries( { 'resolve': 10 } ) )
+
+ with MockResolveRequest( ResolveResponse ):
+ assert_that( ycm.ResolveCompletionItem( item ), equal_to( True ) )
+ assert_that( ycm.CompletionRequestReady() )
+ response = ycm.GetCompletionResponse()
+ post_vim_message.assert_not_called()
+
+ assert_that(
+ response,
+ has_entries( {
+ 'completion': has_entries( {
+ 'word': 'insertion_text',
+ 'abbr': 'menu_text',
+ 'menu': 'extra_menu_info',
+ 'info': 'detailed_info\ndoc_string with more info',
+ 'kind': 'k',
+ 'dup': 1,
+ 'empty': 1
+ } )
} )
- } )
- )
-
- item = response[ 'completion' ]
-
- with MockResolveRequest( ServerError( 'must not be called' ) ):
- assert_that( ycm.ResolveCompletionItem( item ), equal_to( False ) )
- post_vim_message.assert_not_called()
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.client.base_request._logger', autospec = True )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def ResolveCompletionRequest_ResponseContainsErrors_test( post_vim_message,
- logger,
- ycm ):
-
- def CompletionResponse( *args ):
- return {
- 'completions': [ {
- 'insertion_text': 'insertion_text',
- 'menu_text': 'menu_text',
- 'extra_menu_info': 'extra_menu_info',
- 'detailed_info': 'detailed_info',
- 'kind': 'kind',
- 'extra_data': {
- 'doc_string': 'doc_string',
- 'resolve': 10
- }
- } ],
- 'completion_start_column': 3,
- 'errors': []
- }
-
- def ResolveResponse( *args ):
- return {
- 'completion': {
- 'insertion_text': 'insertion_text',
- 'menu_text': 'menu_text',
- 'extra_menu_info': 'extra_menu_info',
- 'detailed_info': 'detailed_info',
- 'kind': 'kind',
- 'extra_data': {
- 'doc_string': 'doc_string with more info'
- }
- },
- 'errors': [ {
- 'exception': {
- 'TYPE': 'Exception'
+ )
+
+ item = response[ 'completion' ]
+
+ with MockResolveRequest( ServerError( 'must not be called' ) ):
+ assert_that( ycm.ResolveCompletionItem( item ), equal_to( False ) )
+ post_vim_message.assert_not_called()
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.client.base_request._logger', autospec = True )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_ResolveCompletionRequest_ResponseContainsErrors( self,
+ ycm,
+ post_vim_message,
+ logger ):
+
+ def CompletionResponse( *args ):
+ return {
+ 'completions': [ {
+ 'insertion_text': 'insertion_text',
+ 'menu_text': 'menu_text',
+ 'extra_menu_info': 'extra_menu_info',
+ 'detailed_info': 'detailed_info',
+ 'kind': 'kind',
+ 'extra_data': {
+ 'doc_string': 'doc_string',
+ 'resolve': 10
+ }
+ } ],
+ 'completion_start_column': 3,
+ 'errors': []
+ }
+
+ def ResolveResponse( *args ):
+ return {
+ 'completion': {
+ 'insertion_text': 'insertion_text',
+ 'menu_text': 'menu_text',
+ 'extra_menu_info': 'extra_menu_info',
+ 'detailed_info': 'detailed_info',
+ 'kind': 'kind',
+ 'extra_data': {
+ 'doc_string': 'doc_string with more info'
+ }
},
- 'message': 'message',
- 'traceback': 'traceback'
- } ]
- }
-
- current_buffer = VimBuffer( 'buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with MockCompletionRequest( CompletionResponse ):
- ycm.SendCompletionRequest()
- assert_that( ycm.CompletionRequestReady() )
- response = ycm.GetCompletionResponse()
-
- post_vim_message.assert_not_called()
- assert_that(
- response,
- has_entries( {
- 'completions': contains_exactly( has_entries( {
- 'word': 'insertion_text',
- 'abbr': 'menu_text',
- 'menu': 'extra_menu_info',
- 'info': 'detailed_info\ndoc_string',
- 'kind': 'k',
- 'dup': 1,
- 'empty': 1
- } ) ),
- 'completion_start_column': 3
- } )
- )
-
- item = response[ 'completions' ][ 0 ]
- assert_that( json.loads( item[ 'user_data' ] ),
- has_entries( { 'resolve': 10 } ) )
-
- with MockResolveRequest( ResolveResponse ):
- assert_that( ycm.ResolveCompletionItem( item ), equal_to( True ) )
- assert_that( ycm.CompletionRequestReady() )
- response = ycm.GetCompletionResponse()
-
- post_vim_message.assert_has_exact_calls( [
- call( 'Exception: message', truncate = True )
- ] )
- assert_that(
- response,
- has_entries( {
- 'completion': has_entries( {
- 'word': 'insertion_text',
- 'abbr': 'menu_text',
- 'menu': 'extra_menu_info',
- 'info': 'detailed_info\ndoc_string with more info',
- 'kind': 'k',
- 'dup': 1,
- 'empty': 1
+ 'errors': [ {
+ 'exception': {
+ 'TYPE': 'Exception'
+ },
+ 'message': 'message',
+ 'traceback': 'traceback'
+ } ]
+ }
+
+ current_buffer = VimBuffer( 'buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with MockCompletionRequest( CompletionResponse ):
+ ycm.SendCompletionRequest()
+ assert_that( ycm.CompletionRequestReady() )
+ response = ycm.GetCompletionResponse()
+
+ post_vim_message.assert_not_called()
+ assert_that(
+ response,
+ has_entries( {
+ 'completions': contains_exactly( has_entries( {
+ 'word': 'insertion_text',
+ 'abbr': 'menu_text',
+ 'menu': 'extra_menu_info',
+ 'info': 'detailed_info\ndoc_string',
+ 'kind': 'k',
+ 'dup': 1,
+ 'empty': 1
+ } ) ),
+ 'completion_start_column': 3
} )
- } )
- )
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def ResolveCompletionItem_NoUserData_test( post_vim_message, ycm ):
- def CompletionResponse( *args ):
- return {
- 'completions': [ {
- 'insertion_text': 'insertion_text',
- 'menu_text': 'menu_text',
- 'extra_menu_info': 'extra_menu_info',
- 'detailed_info': 'detailed_info',
- 'kind': 'kind'
- } ],
- 'completion_start_column': 3,
- 'errors': []
- }
-
- current_buffer = VimBuffer( 'buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with MockCompletionRequest( CompletionResponse ):
- ycm.SendCompletionRequest()
- assert_that( ycm.CompletionRequestReady() )
- response = ycm.GetCompletionResponse()
-
- post_vim_message.assert_not_called()
- assert_that(
- response,
- has_entries( {
- 'completions': contains_exactly( has_entries( {
- 'word': 'insertion_text',
- 'abbr': 'menu_text',
- 'menu': 'extra_menu_info',
- 'info': 'detailed_info',
- 'kind': 'k',
- 'dup': 1,
- 'empty': 1
- } ) ),
- 'completion_start_column': 3
- } )
- )
-
- item = response[ 'completions' ][ 0 ]
- item.pop( 'user_data' )
-
- with MockResolveRequest( ServerError( 'must not be called' ) ):
- assert_that( ycm.ResolveCompletionItem( item ), equal_to( False ) )
- post_vim_message.assert_not_called()
-
-
-@YouCompleteMeInstance()
-def ResolveCompletionItem_NoRequest_test( ycm ):
- assert_that( ycm.GetCurrentCompletionRequest(), equal_to( None ) )
- assert_that( ycm.ResolveCompletionItem( {} ), equal_to( False ) )
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.client.base_request._logger', autospec = True )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def ResolveCompletionRequest_ServerError_test( post_vim_message, logger, ycm ):
-
- def ServerResponse( *args ):
- return {
- 'completions': [ {
- 'insertion_text': 'insertion_text',
- 'menu_text': 'menu_text',
- 'extra_menu_info': 'extra_menu_info',
- 'detailed_info': 'detailed_info',
- 'kind': 'kind',
- 'extra_data': {
- 'doc_string': 'doc_string',
- 'resolve': 10
- }
- } ],
- 'completion_start_column': 3,
- 'errors': []
- }
-
- current_buffer = VimBuffer( 'buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with MockCompletionRequest( ServerResponse ):
- ycm.SendCompletionRequest()
- assert_that( ycm.CompletionRequestReady() )
- response = ycm.GetCompletionResponse()
-
- post_vim_message.assert_not_called()
- assert_that(
- response,
- has_entries( {
- 'completions': contains_exactly( has_entries( {
- 'word': 'insertion_text',
- 'abbr': 'menu_text',
- 'menu': 'extra_menu_info',
- 'info': 'detailed_info\ndoc_string',
- 'kind': 'k',
- 'dup': 1,
- 'empty': 1
- } ) ),
- 'completion_start_column': 3
- } )
- )
-
- item = response[ 'completions' ][ 0 ]
- assert_that( json.loads( item[ 'user_data' ] ),
- has_entries( { 'resolve': 10 } ) )
-
- with MockResolveRequest( ServerError( 'Server error' ) ):
- ycm.ResolveCompletionItem( item )
- assert_that( ycm.CompletionRequestReady() )
- response = ycm.GetCompletionResponse()
-
- logger.exception.assert_called_with( 'Error while handling server '
- 'response' )
- post_vim_message.assert_has_exact_calls( [
- call( 'Server error', truncate = True )
- ] )
+ )
+
+ item = response[ 'completions' ][ 0 ]
+ assert_that( json.loads( item[ 'user_data' ] ),
+ has_entries( { 'resolve': 10 } ) )
+
+ with MockResolveRequest( ResolveResponse ):
+ assert_that( ycm.ResolveCompletionItem( item ), equal_to( True ) )
+ assert_that( ycm.CompletionRequestReady() )
+ response = ycm.GetCompletionResponse()
+
+ post_vim_message.assert_has_exact_calls( [
+ call( 'Exception: message', truncate = True )
+ ] )
+ assert_that(
+ response,
+ has_entries( {
+ 'completion': has_entries( {
+ 'word': 'insertion_text',
+ 'abbr': 'menu_text',
+ 'menu': 'extra_menu_info',
+ 'info': 'detailed_info\ndoc_string with more info',
+ 'kind': 'k',
+ 'dup': 1,
+ 'empty': 1
+ } )
+ } )
+ )
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_ResolveCompletionItem_NoUserData( self, ycm, post_vim_message ):
+ def CompletionResponse( *args ):
+ return {
+ 'completions': [ {
+ 'insertion_text': 'insertion_text',
+ 'menu_text': 'menu_text',
+ 'extra_menu_info': 'extra_menu_info',
+ 'detailed_info': 'detailed_info',
+ 'kind': 'kind'
+ } ],
+ 'completion_start_column': 3,
+ 'errors': []
+ }
+
+ current_buffer = VimBuffer( 'buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with MockCompletionRequest( CompletionResponse ):
+ ycm.SendCompletionRequest()
+ assert_that( ycm.CompletionRequestReady() )
+ response = ycm.GetCompletionResponse()
+
+ post_vim_message.assert_not_called()
+ assert_that(
+ response,
+ has_entries( {
+ 'completions': contains_exactly( has_entries( {
+ 'word': 'insertion_text',
+ 'abbr': 'menu_text',
+ 'menu': 'extra_menu_info',
+ 'info': 'detailed_info',
+ 'kind': 'k',
+ 'dup': 1,
+ 'empty': 1
+ } ) ),
+ 'completion_start_column': 3
+ } )
+ )
+
+ item = response[ 'completions' ][ 0 ]
+ item.pop( 'user_data' )
+
+ with MockResolveRequest( ServerError( 'must not be called' ) ):
+ assert_that( ycm.ResolveCompletionItem( item ), equal_to( False ) )
+ post_vim_message.assert_not_called()
+
+
+ @YouCompleteMeInstance()
+ def test_ResolveCompletionItem_NoRequest( self, ycm ):
+ assert_that( ycm.GetCurrentCompletionRequest(), equal_to( None ) )
+ assert_that( ycm.ResolveCompletionItem( {} ), equal_to( False ) )
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.client.base_request._logger', autospec = True )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_ResolveCompletionRequest_ServerError(
+ self, ycm, post_vim_message, logger ):
+
+ def ServerResponse( *args ):
+ return {
+ 'completions': [ {
+ 'insertion_text': 'insertion_text',
+ 'menu_text': 'menu_text',
+ 'extra_menu_info': 'extra_menu_info',
+ 'detailed_info': 'detailed_info',
+ 'kind': 'kind',
+ 'extra_data': {
+ 'doc_string': 'doc_string',
+ 'resolve': 10
+ }
+ } ],
+ 'completion_start_column': 3,
+ 'errors': []
+ }
+
+ current_buffer = VimBuffer( 'buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with MockCompletionRequest( ServerResponse ):
+ ycm.SendCompletionRequest()
+ assert_that( ycm.CompletionRequestReady() )
+ response = ycm.GetCompletionResponse()
+
+ post_vim_message.assert_not_called()
+ assert_that(
+ response,
+ has_entries( {
+ 'completions': contains_exactly( has_entries( {
+ 'word': 'insertion_text',
+ 'abbr': 'menu_text',
+ 'menu': 'extra_menu_info',
+ 'info': 'detailed_info\ndoc_string',
+ 'kind': 'k',
+ 'dup': 1,
+ 'empty': 1
+ } ) ),
+ 'completion_start_column': 3
+ } )
+ )
+
+ item = response[ 'completions' ][ 0 ]
+ assert_that( json.loads( item[ 'user_data' ] ),
+ has_entries( { 'resolve': 10 } ) )
+
+ with MockResolveRequest( ServerError( 'Server error' ) ):
+ ycm.ResolveCompletionItem( item )
+ assert_that( ycm.CompletionRequestReady() )
+ response = ycm.GetCompletionResponse()
+
+ logger.exception.assert_called_with( 'Error while handling server '
+ 'response' )
+ post_vim_message.assert_has_exact_calls( [
+ call( 'Server error', truncate = True )
+ ] )
diff --git a/python/ycm/tests/conftest.py b/python/ycm/tests/conftest.py
deleted file mode 100644
index 71ca3a429a..0000000000
--- a/python/ycm/tests/conftest.py
+++ /dev/null
@@ -1,143 +0,0 @@
-# Copyright (C) 2016-2020 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 .
-
-from ycm.tests.test_utils import MockVimModule
-MockVimModule()
-
-import contextlib
-import pytest
-import time
-import warnings
-from urllib.error import HTTPError, URLError
-
-from ycm.client.base_request import BaseRequest
-from ycm.tests import test_utils
-from ycm.youcompleteme import YouCompleteMe
-from ycmd.utils import CloseStandardStreams, WaitUntilProcessIsTerminated
-
-
-def setUpAndTearDown():
- # 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' )
- try:
- yield
- finally:
- warnings.resetwarnings()
-
-
-# The default options which are required for a working YouCompleteMe object.
-DEFAULT_CLIENT_OPTIONS = {
- # YCM options
- 'g:ycm_log_level': 'info',
- 'g:ycm_keep_logfiles': 0,
- 'g:ycm_extra_conf_vim_data': [],
- 'g:ycm_server_python_interpreter': '',
- 'g:ycm_show_diagnostics_ui': 1,
- 'g:ycm_enable_diagnostic_signs': 1,
- 'g:ycm_enable_diagnostic_highlighting': 0,
- 'g:ycm_echo_current_diagnostic': 1,
- 'g:ycm_filter_diagnostics': {},
- 'g:ycm_always_populate_location_list': 0,
- 'g:ycm_collect_identifiers_from_tags_files': 0,
- 'g:ycm_seed_identifiers_with_syntax': 0,
- 'g:ycm_goto_buffer_command': 'same-buffer',
- 'g:ycm_update_diagnostics_in_insert_mode': 1,
- # ycmd options
- 'g:ycm_auto_trigger': 1,
- 'g:ycm_min_num_of_chars_for_completion': 2,
- 'g:ycm_semantic_triggers': {},
- 'g:ycm_filetype_specific_completion_to_disable': { 'gitcommit': 1 },
- 'g:ycm_max_num_candidates': 50,
- 'g:ycm_max_diagnostics_to_display': 30,
- 'g:ycm_disable_signature_help': 0,
-}
-
-
-@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 '
- f'for { timeout } seconds, aborting.' )
- if _IsReady():
- return
- except ( URLError, HTTPError ):
- pass
- finally:
- time.sleep( 0.1 )
-
-
-def StopServer( ycm ):
- try:
- ycm.OnVimLeave()
- WaitUntilProcessIsTerminated( ycm._server_popen )
- CloseStandardStreams( ycm._server_popen )
- except Exception:
- pass
-
-
-@pytest.fixture
-def ycm( request ):
- custom_options = request.param
- with UserOptions( custom_options ):
- ycm = YouCompleteMe()
- WaitUntilReady()
- ycm.CheckIfServerIsReady()
- try:
- test_utils.VIM_MATCHES_FOR_WINDOW.clear()
- yield ycm
- finally:
- StopServer( ycm )
-
-
-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.
-
- Example usage:
-
- from ycm.tests import YouCompleteMeInstance
-
- @YouCompleteMeInstance( { 'log_level': 'debug',
- 'keep_logfiles': 1 } )
- def Debug_test( ycm ):
- ...
- """
- return pytest.mark.parametrize(
- 'ycm',
- [ custom_options ],
- ids = [ '' ],
- indirect = True )
diff --git a/python/ycm/tests/diagnostic_filter_test.py b/python/ycm/tests/diagnostic_filter_test.py
index 3591feb932..6aabec5362 100644
--- a/python/ycm/tests/diagnostic_filter_test.py
+++ b/python/ycm/tests/diagnostic_filter_test.py
@@ -19,6 +19,7 @@
MockVimModule()
from hamcrest import assert_that, equal_to
+from unittest import TestCase
from ycm.diagnostic_filter import DiagnosticFilter
@@ -45,91 +46,92 @@ def _CreateFilterForTypes( opts, types ):
return DiagnosticFilter.CreateFromOptions( opts ).SubsetForTypes( types )
-def RegexFilter_test():
- opts = _JavaFilter( { 'regex' : 'taco' } )
- f = _CreateFilterForTypes( opts, [ 'java' ] )
+class DiagnosticFilterTest( TestCase ):
+ def test_RegexFilter( self ):
+ opts = _JavaFilter( { 'regex' : 'taco' } )
+ f = _CreateFilterForTypes( opts, [ 'java' ] )
- _assert_rejects( f, 'This is a Taco' )
- _assert_accepts( f, 'This is a Burrito' )
+ _assert_rejects( f, 'This is a Taco' )
+ _assert_accepts( f, 'This is a Burrito' )
-def RegexSingleList_test():
- opts = _JavaFilter( { 'regex' : [ 'taco' ] } )
- f = _CreateFilterForTypes( opts, [ 'java' ] )
+ def test_RegexSingleList( self ):
+ opts = _JavaFilter( { 'regex' : [ 'taco' ] } )
+ f = _CreateFilterForTypes( opts, [ 'java' ] )
- _assert_rejects( f, 'This is a Taco' )
- _assert_accepts( f, 'This is a Burrito' )
+ _assert_rejects( f, 'This is a Taco' )
+ _assert_accepts( f, 'This is a Burrito' )
-def RegexMultiList_test():
- opts = _JavaFilter( { 'regex' : [ 'taco', 'burrito' ] } )
- f = _CreateFilterForTypes( opts, [ 'java' ] )
+ def test_RegexMultiList( self ):
+ opts = _JavaFilter( { 'regex' : [ 'taco', 'burrito' ] } )
+ f = _CreateFilterForTypes( opts, [ 'java' ] )
- _assert_rejects( f, 'This is a Taco' )
- _assert_rejects( f, 'This is a Burrito' )
+ _assert_rejects( f, 'This is a Taco' )
+ _assert_rejects( f, 'This is a Burrito' )
-def RegexNotFiltered_test():
- opts = _JavaFilter( { 'regex' : 'taco' } )
- f = _CreateFilterForTypes( opts, [ 'cs' ] )
+ def test_RegexNotFiltered( self ):
+ opts = _JavaFilter( { 'regex' : 'taco' } )
+ f = _CreateFilterForTypes( opts, [ 'cs' ] )
- _assert_accepts( f, 'This is a Taco' )
- _assert_accepts( f, 'This is a Burrito' )
+ _assert_accepts( f, 'This is a Taco' )
+ _assert_accepts( f, 'This is a Burrito' )
-def LevelWarnings_test():
- opts = _JavaFilter( { 'level' : 'warning' } )
- f = _CreateFilterForTypes( opts, [ 'java' ] )
+ def test_LevelWarnings( self ):
+ opts = _JavaFilter( { 'level' : 'warning' } )
+ f = _CreateFilterForTypes( opts, [ 'java' ] )
- _assert_rejects( f, { 'text' : 'This is an unimportant taco',
- 'kind' : 'WARNING' } )
- _assert_accepts( f, { 'text' : 'This taco will be shown',
- 'kind' : 'ERROR' } )
+ _assert_rejects( f, { 'text' : 'This is an unimportant taco',
+ 'kind' : 'WARNING' } )
+ _assert_accepts( f, { 'text' : 'This taco will be shown',
+ 'kind' : 'ERROR' } )
-def LevelErrors_test():
- opts = _JavaFilter( { 'level' : 'error' } )
- f = _CreateFilterForTypes( opts, [ 'java' ] )
+ def test_LevelErrors( self ):
+ opts = _JavaFilter( { 'level' : 'error' } )
+ f = _CreateFilterForTypes( opts, [ 'java' ] )
- _assert_accepts( f, { 'text' : 'This is an IMPORTANT taco',
- 'kind' : 'WARNING' } )
- _assert_rejects( f, { 'text' : 'This taco will NOT be shown',
- 'kind' : 'ERROR' } )
+ _assert_accepts( f, { 'text' : 'This is an IMPORTANT taco',
+ 'kind' : 'WARNING' } )
+ _assert_rejects( f, { 'text' : 'This taco will NOT be shown',
+ 'kind' : 'ERROR' } )
-def MultipleFilterTypesTypeTest_test():
+ def test_MultipleFilterTypesTypeTest( self ):
- opts = _JavaFilter( { 'regex' : '.*taco.*',
- 'level' : 'warning' } )
- f = _CreateFilterForTypes( opts, [ 'java' ] )
+ opts = _JavaFilter( { 'regex' : '.*taco.*',
+ 'level' : 'warning' } )
+ f = _CreateFilterForTypes( opts, [ 'java' ] )
- _assert_rejects( f, { 'text' : 'This is an unimportant taco',
- 'kind' : 'WARNING' } )
- _assert_rejects( f, { 'text' : 'This taco will NOT be shown',
- 'kind' : 'ERROR' } )
- _assert_accepts( f, { 'text' : 'This burrito WILL be shown',
- 'kind' : 'ERROR' } )
+ _assert_rejects( f, { 'text' : 'This is an unimportant taco',
+ 'kind' : 'WARNING' } )
+ _assert_rejects( f, { 'text' : 'This taco will NOT be shown',
+ 'kind' : 'ERROR' } )
+ _assert_accepts( f, { 'text' : 'This burrito WILL be shown',
+ 'kind' : 'ERROR' } )
-def MergeMultipleFiletypes_test():
+ def test_MergeMultipleFiletypes( self ):
- opts = { 'filter_diagnostics' : {
- 'java' : { 'regex' : '.*taco.*' },
- 'xml' : { 'regex' : '.*burrito.*' } } }
+ opts = { 'filter_diagnostics' : {
+ 'java' : { 'regex' : '.*taco.*' },
+ 'xml' : { 'regex' : '.*burrito.*' } } }
- f = _CreateFilterForTypes( opts, [ 'java', 'xml' ] )
+ f = _CreateFilterForTypes( opts, [ 'java', 'xml' ] )
- _assert_rejects( f, 'This is a Taco' )
- _assert_rejects( f, 'This is a Burrito' )
- _assert_accepts( f, 'This is some Nachos' )
+ _assert_rejects( f, 'This is a Taco' )
+ _assert_rejects( f, 'This is a Burrito' )
+ _assert_accepts( f, 'This is some Nachos' )
-def CommaSeparatedFiletypes_test():
+ def test_CommaSeparatedFiletypes( self ):
- opts = { 'filter_diagnostics' : {
- 'java,c,cs' : { 'regex' : '.*taco.*' } } }
+ opts = { 'filter_diagnostics' : {
+ 'java,c,cs' : { 'regex' : '.*taco.*' } } }
- f = _CreateFilterForTypes( opts, [ 'cs' ] )
+ f = _CreateFilterForTypes( opts, [ 'cs' ] )
- _assert_rejects( f, 'This is a Taco' )
- _assert_accepts( f, 'This is a Burrito' )
+ _assert_rejects( f, 'This is a Taco' )
+ _assert_accepts( f, 'This is a Burrito' )
diff --git a/python/ycm/tests/event_notification_test.py b/python/ycm/tests/event_notification_test.py
index 5c057f5efa..013407c7c4 100644
--- a/python/ycm/tests/event_notification_test.py
+++ b/python/ycm/tests/event_notification_test.py
@@ -32,6 +32,7 @@
from hamcrest import ( assert_that, contains_exactly, empty, equal_to,
has_entries, has_entry, has_item, has_items, has_key,
is_not )
+from unittest import TestCase
from unittest.mock import call, MagicMock, patch
@@ -85,183 +86,6 @@ def MockEventNotification( response_method, native_filetype_completer = True ):
yield
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-@YouCompleteMeInstance()
-def EventNotification_FileReadyToParse_NonDiagnostic_Error_test(
- post_vim_message, ycm ):
-
- # This test validates the behaviour of YouCompleteMe.HandleFileParseRequest
- # in combination with YouCompleteMe.OnFileReadyToParse when the completer
- # raises an exception handling FileReadyToParse event notification
- ERROR_TEXT = 'Some completer response text'
-
- def ErrorResponse( *args ):
- raise ServerError( ERROR_TEXT )
-
- with MockArbitraryBuffer( 'some_filetype' ):
- with MockEventNotification( ErrorResponse ):
- ycm.OnFileReadyToParse()
- assert_that( ycm.FileParseRequestReady() )
- ycm.HandleFileParseRequest()
-
- # The first call raises a warning
- post_vim_message.assert_has_exact_calls( [
- call( ERROR_TEXT, truncate = True )
- ] )
-
- # Subsequent calls don't re-raise the warning
- ycm.HandleFileParseRequest()
- post_vim_message.assert_has_exact_calls( [
- call( ERROR_TEXT, truncate = True )
- ] )
-
- assert_that( not ycm.ShouldResendFileParseRequest() )
-
- # But it does if a subsequent event raises again
- ycm.OnFileReadyToParse()
- assert_that( ycm.FileParseRequestReady() )
- ycm.HandleFileParseRequest()
- post_vim_message.assert_has_exact_calls( [
- call( ERROR_TEXT, truncate = True ),
- call( ERROR_TEXT, truncate = True )
- ] )
-
- assert_that( not ycm.ShouldResendFileParseRequest() )
-
-
-@YouCompleteMeInstance()
-def EventNotification_FileReadyToParse_NonDiagnostic_Error_NonNative_test(
- ycm ):
-
- test_utils.VIM_MATCHES = []
- test_utils.VIM_SIGNS = []
-
- with MockArbitraryBuffer( 'some_filetype' ):
- with MockEventNotification( None, False ):
- ycm.OnFileReadyToParse()
- ycm.HandleFileParseRequest()
- assert_that( test_utils.VIM_MATCHES, empty() )
- assert_that( test_utils.VIM_SIGNS, empty() )
- assert_that( not ycm.ShouldResendFileParseRequest() )
-
-
-@YouCompleteMeInstance()
-def EventNotification_FileReadyToParse_NonDiagnostic_ConfirmExtraConf_test(
- ycm ):
-
- # This test validates the behaviour of YouCompleteMe.HandleFileParseRequest
- # in combination with YouCompleteMe.OnFileReadyToParse when the completer
- # raises the (special) UnknownExtraConf exception
- FILE_NAME = 'a_file'
- MESSAGE = ( 'Found ' + FILE_NAME + '. Load? \n\n(Question can be '
- 'turned off with options, see YCM docs)' )
-
- def UnknownExtraConfResponse( *args ):
- raise UnknownExtraConf( FILE_NAME )
-
- with patch( 'ycm.client.base_request.BaseRequest.PostDataToHandler',
- new_callable = ExtendedMock ) as post_data_to_handler:
- with MockArbitraryBuffer( 'some_filetype' ):
- with MockEventNotification( UnknownExtraConfResponse ):
-
- # When the user accepts the extra conf, we load it
- with patch( 'ycm.vimsupport.PresentDialog',
- return_value = 0,
- new_callable = ExtendedMock ) as present_dialog:
- ycm.OnFileReadyToParse()
- assert_that( ycm.FileParseRequestReady() )
- ycm.HandleFileParseRequest()
-
- present_dialog.assert_has_exact_calls( [
- PresentDialog_Confirm_Call( MESSAGE ),
- ] )
- post_data_to_handler.assert_has_exact_calls( [
- call( { 'filepath': FILE_NAME }, 'load_extra_conf_file' )
- ] )
-
- # Subsequent calls don't re-raise the warning
- ycm.HandleFileParseRequest()
-
- present_dialog.assert_has_exact_calls( [
- PresentDialog_Confirm_Call( MESSAGE )
- ] )
- post_data_to_handler.assert_has_exact_calls( [
- call( { 'filepath': FILE_NAME }, 'load_extra_conf_file' )
- ] )
-
- assert_that( ycm.ShouldResendFileParseRequest() )
-
- # But it does if a subsequent event raises again
- ycm.OnFileReadyToParse()
- assert_that( ycm.FileParseRequestReady() )
- ycm.HandleFileParseRequest()
-
- present_dialog.assert_has_exact_calls( [
- PresentDialog_Confirm_Call( MESSAGE ),
- PresentDialog_Confirm_Call( MESSAGE ),
- ] )
- post_data_to_handler.assert_has_exact_calls( [
- call( { 'filepath': FILE_NAME }, 'load_extra_conf_file' ),
- call( { 'filepath': FILE_NAME }, 'load_extra_conf_file' )
- ] )
-
- assert_that( ycm.ShouldResendFileParseRequest() )
-
- post_data_to_handler.reset_mock()
-
- # When the user rejects the extra conf, we reject it
- with patch( 'ycm.vimsupport.PresentDialog',
- return_value = 1,
- new_callable = ExtendedMock ) as present_dialog:
- ycm.OnFileReadyToParse()
- assert_that( ycm.FileParseRequestReady() )
- ycm.HandleFileParseRequest()
-
- present_dialog.assert_has_exact_calls( [
- PresentDialog_Confirm_Call( MESSAGE ),
- ] )
- post_data_to_handler.assert_has_exact_calls( [
- call( { 'filepath': FILE_NAME }, 'ignore_extra_conf_file' )
- ] )
-
- # Subsequent calls don't re-raise the warning
- ycm.HandleFileParseRequest()
-
- present_dialog.assert_has_exact_calls( [
- PresentDialog_Confirm_Call( MESSAGE )
- ] )
- post_data_to_handler.assert_has_exact_calls( [
- call( { 'filepath': FILE_NAME }, 'ignore_extra_conf_file' )
- ] )
-
- assert_that( ycm.ShouldResendFileParseRequest() )
-
- # But it does if a subsequent event raises again
- ycm.OnFileReadyToParse()
- assert_that( ycm.FileParseRequestReady() )
- ycm.HandleFileParseRequest()
-
- present_dialog.assert_has_exact_calls( [
- PresentDialog_Confirm_Call( MESSAGE ),
- PresentDialog_Confirm_Call( MESSAGE ),
- ] )
- post_data_to_handler.assert_has_exact_calls( [
- call( { 'filepath': FILE_NAME }, 'ignore_extra_conf_file' ),
- call( { 'filepath': FILE_NAME }, 'ignore_extra_conf_file' )
- ] )
-
- assert_that( ycm.ShouldResendFileParseRequest() )
-
-
-@YouCompleteMeInstance()
-def EventNotification_FileReadyToParse_Diagnostic_Error_Native_test( ycm ):
- test_utils.VIM_SIGNS = []
-
- _Check_FileReadyToParse_Diagnostic_Error( ycm )
- _Check_FileReadyToParse_Diagnostic_Warning( ycm )
- _Check_FileReadyToParse_Diagnostic_Clean( ycm )
-
-
def _Check_FileReadyToParse_Diagnostic_Error( ycm ):
# Tests Vim sign placement and error/warning count python API
# when one error is returned.
@@ -373,216 +197,397 @@ def _Check_FileReadyToParse_Diagnostic_Clean( ycm ):
assert_that( not ycm.ShouldResendFileParseRequest() )
-@patch( 'ycm.youcompleteme.YouCompleteMe._AddUltiSnipsDataIfNeeded' )
-@YouCompleteMeInstance( { 'g:ycm_collect_identifiers_from_tags_files': 1 } )
-def EventNotification_FileReadyToParse_TagFiles_UnicodeWorkingDirectory_test(
- add_ultisnips_data_if_needed, ycm ):
- unicode_dir = PathToTestFile( 'uni¢od€' )
- current_buffer_file = PathToTestFile( 'uni¢𐍈d€', 'current_buffer' )
- current_buffer = VimBuffer( name = current_buffer_file,
- contents = [ 'current_buffer_contents' ],
- filetype = 'some_filetype' )
+class EventNotificationTest( TestCase ):
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ @YouCompleteMeInstance()
+ def test_EventNotification_FileReadyToParse_NonDiagnostic_Error(
+ self, ycm, post_vim_message ):
- with patch( 'ycm.client.event_notification.EventNotification.'
- 'PostDataToHandlerAsync' ) as post_data_to_handler_async:
- with CurrentWorkingDirectory( unicode_dir ):
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 5 ) ):
+ # This test validates the behaviour of YouCompleteMe.HandleFileParseRequest
+ # in combination with YouCompleteMe.OnFileReadyToParse when the completer
+ # raises an exception handling FileReadyToParse event notification
+ ERROR_TEXT = 'Some completer response text'
+
+ def ErrorResponse( *args ):
+ raise ServerError( ERROR_TEXT )
+
+ with MockArbitraryBuffer( 'some_filetype' ):
+ with MockEventNotification( ErrorResponse ):
ycm.OnFileReadyToParse()
+ assert_that( ycm.FileParseRequestReady() )
+ ycm.HandleFileParseRequest()
- assert_that(
- # Positional arguments passed to PostDataToHandlerAsync.
- post_data_to_handler_async.call_args[ 0 ],
- contains_exactly(
- has_entries( {
- 'filepath': current_buffer_file,
- 'line_num': 1,
- 'column_num': 6,
- 'file_data': has_entries( {
- current_buffer_file: has_entries( {
- 'contents': 'current_buffer_contents\n',
- 'filetypes': [ 'some_filetype' ]
- } )
+ # The first call raises a warning
+ post_vim_message.assert_has_exact_calls( [
+ call( ERROR_TEXT, truncate = True )
+ ] )
+
+ # Subsequent calls don't re-raise the warning
+ ycm.HandleFileParseRequest()
+ post_vim_message.assert_has_exact_calls( [
+ call( ERROR_TEXT, truncate = True )
+ ] )
+
+ assert_that( not ycm.ShouldResendFileParseRequest() )
+
+ # But it does if a subsequent event raises again
+ ycm.OnFileReadyToParse()
+ assert_that( ycm.FileParseRequestReady() )
+ ycm.HandleFileParseRequest()
+ post_vim_message.assert_has_exact_calls( [
+ call( ERROR_TEXT, truncate = True ),
+ call( ERROR_TEXT, truncate = True )
+ ] )
+
+ assert_that( not ycm.ShouldResendFileParseRequest() )
+
+
+ @YouCompleteMeInstance()
+ def test_EventNotification_FileReadyToParse_NonDiagnostic_Error_NonNative(
+ self, ycm ):
+
+ test_utils.VIM_MATCHES = []
+ test_utils.VIM_SIGNS = []
+
+ with MockArbitraryBuffer( 'some_filetype' ):
+ with MockEventNotification( None, False ):
+ ycm.OnFileReadyToParse()
+ ycm.HandleFileParseRequest()
+ assert_that( test_utils.VIM_MATCHES, empty() )
+ assert_that( test_utils.VIM_SIGNS, empty() )
+ assert_that( not ycm.ShouldResendFileParseRequest() )
+
+
+ @YouCompleteMeInstance()
+ def test_EventNotification_FileReadyToParse_NonDiagnostic_ConfirmExtraConf(
+ self, ycm ):
+
+ # This test validates the behaviour of YouCompleteMe.HandleFileParseRequest
+ # in combination with YouCompleteMe.OnFileReadyToParse when the completer
+ # raises the (special) UnknownExtraConf exception
+ FILE_NAME = 'a_file'
+ MESSAGE = ( 'Found ' + FILE_NAME + '. Load? \n\n(Question can be '
+ 'turned off with options, see YCM docs)' )
+
+ def UnknownExtraConfResponse( *args ):
+ raise UnknownExtraConf( FILE_NAME )
+
+ with patch( 'ycm.client.base_request.BaseRequest.PostDataToHandler',
+ new_callable = ExtendedMock ) as post_data_to_handler:
+ with MockArbitraryBuffer( 'some_filetype' ):
+ with MockEventNotification( UnknownExtraConfResponse ):
+
+ # When the user accepts the extra conf, we load it
+ with patch( 'ycm.vimsupport.PresentDialog',
+ return_value = 0,
+ new_callable = ExtendedMock ) as present_dialog:
+ ycm.OnFileReadyToParse()
+ assert_that( ycm.FileParseRequestReady() )
+ ycm.HandleFileParseRequest()
+
+ present_dialog.assert_has_exact_calls( [
+ PresentDialog_Confirm_Call( MESSAGE ),
+ ] )
+ post_data_to_handler.assert_has_exact_calls( [
+ call( { 'filepath': FILE_NAME }, 'load_extra_conf_file' )
+ ] )
+
+ # Subsequent calls don't re-raise the warning
+ ycm.HandleFileParseRequest()
+
+ present_dialog.assert_has_exact_calls( [
+ PresentDialog_Confirm_Call( MESSAGE )
+ ] )
+ post_data_to_handler.assert_has_exact_calls( [
+ call( { 'filepath': FILE_NAME }, 'load_extra_conf_file' )
+ ] )
+
+ assert_that( ycm.ShouldResendFileParseRequest() )
+
+ # But it does if a subsequent event raises again
+ ycm.OnFileReadyToParse()
+ assert_that( ycm.FileParseRequestReady() )
+ ycm.HandleFileParseRequest()
+
+ present_dialog.assert_has_exact_calls( [
+ PresentDialog_Confirm_Call( MESSAGE ),
+ PresentDialog_Confirm_Call( MESSAGE ),
+ ] )
+ post_data_to_handler.assert_has_exact_calls( [
+ call( { 'filepath': FILE_NAME }, 'load_extra_conf_file' ),
+ call( { 'filepath': FILE_NAME }, 'load_extra_conf_file' )
+ ] )
+
+ assert_that( ycm.ShouldResendFileParseRequest() )
+
+ post_data_to_handler.reset_mock()
+
+ # When the user rejects the extra conf, we reject it
+ with patch( 'ycm.vimsupport.PresentDialog',
+ return_value = 1,
+ new_callable = ExtendedMock ) as present_dialog:
+ ycm.OnFileReadyToParse()
+ assert_that( ycm.FileParseRequestReady() )
+ ycm.HandleFileParseRequest()
+
+ present_dialog.assert_has_exact_calls( [
+ PresentDialog_Confirm_Call( MESSAGE ),
+ ] )
+ post_data_to_handler.assert_has_exact_calls( [
+ call( { 'filepath': FILE_NAME }, 'ignore_extra_conf_file' )
+ ] )
+
+ # Subsequent calls don't re-raise the warning
+ ycm.HandleFileParseRequest()
+
+ present_dialog.assert_has_exact_calls( [
+ PresentDialog_Confirm_Call( MESSAGE )
+ ] )
+ post_data_to_handler.assert_has_exact_calls( [
+ call( { 'filepath': FILE_NAME }, 'ignore_extra_conf_file' )
+ ] )
+
+ assert_that( ycm.ShouldResendFileParseRequest() )
+
+ # But it does if a subsequent event raises again
+ ycm.OnFileReadyToParse()
+ assert_that( ycm.FileParseRequestReady() )
+ ycm.HandleFileParseRequest()
+
+ present_dialog.assert_has_exact_calls( [
+ PresentDialog_Confirm_Call( MESSAGE ),
+ PresentDialog_Confirm_Call( MESSAGE ),
+ ] )
+ post_data_to_handler.assert_has_exact_calls( [
+ call( { 'filepath': FILE_NAME }, 'ignore_extra_conf_file' ),
+ call( { 'filepath': FILE_NAME }, 'ignore_extra_conf_file' )
+ ] )
+
+ assert_that( ycm.ShouldResendFileParseRequest() )
+
+
+ @YouCompleteMeInstance()
+ def test_EventNotification_FileReadyToParse_Diagnostic_Error_Native(
+ self, ycm ):
+ test_utils.VIM_SIGNS = []
+
+ _Check_FileReadyToParse_Diagnostic_Error( ycm )
+ _Check_FileReadyToParse_Diagnostic_Warning( ycm )
+ _Check_FileReadyToParse_Diagnostic_Clean( ycm )
+
+
+ @patch( 'ycm.youcompleteme.YouCompleteMe._AddUltiSnipsDataIfNeeded' )
+ @YouCompleteMeInstance( { 'g:ycm_collect_identifiers_from_tags_files': 1 } )
+ def test_EventNotification_FileReadyToParse_TagFiles_UnicodeWorkingDirectory(
+ self, ycm, *args ):
+ unicode_dir = PathToTestFile( 'uni¢od€' )
+ current_buffer_file = PathToTestFile( 'uni¢𐍈d€', 'current_buffer' )
+ current_buffer = VimBuffer( name = current_buffer_file,
+ contents = [ 'current_buffer_contents' ],
+ filetype = 'some_filetype' )
+
+ with patch( 'ycm.client.event_notification.EventNotification.'
+ 'PostDataToHandlerAsync' ) as post_data_to_handler_async:
+ with CurrentWorkingDirectory( unicode_dir ):
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 5 ) ):
+ ycm.OnFileReadyToParse()
+
+ assert_that(
+ # Positional arguments passed to PostDataToHandlerAsync.
+ post_data_to_handler_async.call_args[ 0 ],
+ contains_exactly(
+ has_entries( {
+ 'filepath': current_buffer_file,
+ 'line_num': 1,
+ 'column_num': 6,
+ 'file_data': has_entries( {
+ current_buffer_file: has_entries( {
+ 'contents': 'current_buffer_contents\n',
+ 'filetypes': [ 'some_filetype' ]
+ } )
+ } ),
+ 'event_name': 'FileReadyToParse',
+ 'tag_files': has_item( PathToTestFile( 'uni¢od€', 'tags' ) )
} ),
- 'event_name': 'FileReadyToParse',
- 'tag_files': has_item( PathToTestFile( 'uni¢od€', 'tags' ) )
- } ),
- 'event_notification'
+ 'event_notification'
+ )
)
- )
-@patch( 'ycm.youcompleteme.YouCompleteMe._AddUltiSnipsDataIfNeeded' )
-@YouCompleteMeInstance()
-def EventNotification_BufferVisit_BuildRequestForCurrentAndUnsavedBuffers_test(
- add_ultisnips_data_if_needed, ycm ):
-
- current_buffer_file = os.path.realpath( 'current_buffer' )
- current_buffer = VimBuffer( name = current_buffer_file,
- number = 1,
- contents = [ 'current_buffer_contents' ],
- filetype = 'some_filetype',
- modified = False )
- modified_buffer_file = os.path.realpath( 'modified_buffer' )
- modified_buffer = VimBuffer( name = modified_buffer_file,
- number = 2,
- contents = [ 'modified_buffer_contents' ],
- filetype = 'some_filetype',
- modified = True )
-
- unmodified_buffer_file = os.path.realpath( 'unmodified_buffer' )
- unmodified_buffer = VimBuffer( name = unmodified_buffer_file,
- number = 3,
- contents = [ 'unmodified_buffer_contents' ],
+ @patch( 'ycm.youcompleteme.YouCompleteMe._AddUltiSnipsDataIfNeeded' )
+ @YouCompleteMeInstance()
+ def test_EventNotification_BufferVisit_BuildRequestForCurrentAndUnsavedBuffers( # noqa
+ self, ycm, *args ):
+
+ current_buffer_file = os.path.realpath( 'current_buffer' )
+ current_buffer = VimBuffer( name = current_buffer_file,
+ number = 1,
+ contents = [ 'current_buffer_contents' ],
+ filetype = 'some_filetype',
+ modified = False )
+ modified_buffer_file = os.path.realpath( 'modified_buffer' )
+ modified_buffer = VimBuffer( name = modified_buffer_file,
+ number = 2,
+ contents = [ 'modified_buffer_contents' ],
filetype = 'some_filetype',
- modified = False )
+ modified = True )
+
+ unmodified_buffer_file = os.path.realpath( 'unmodified_buffer' )
+ unmodified_buffer = VimBuffer( name = unmodified_buffer_file,
+ number = 3,
+ contents = [ 'unmodified_buffer_contents' ],
+ filetype = 'some_filetype',
+ modified = False )
+
+ with patch( 'ycm.client.event_notification.EventNotification.'
+ 'PostDataToHandlerAsync' ) as post_data_to_handler_async:
+ with MockVimBuffers( [ current_buffer,
+ modified_buffer,
+ unmodified_buffer ],
+ [ current_buffer ],
+ ( 1, 5 ) ):
+ ycm.OnBufferVisit()
- with patch( 'ycm.client.event_notification.EventNotification.'
- 'PostDataToHandlerAsync' ) as post_data_to_handler_async:
- with MockVimBuffers( [ current_buffer, modified_buffer, unmodified_buffer ],
- [ current_buffer ],
- ( 1, 5 ) ):
- ycm.OnBufferVisit()
+ assert_that(
+ # Positional arguments passed to PostDataToHandlerAsync.
+ post_data_to_handler_async.call_args[ 0 ],
+ contains_exactly(
+ has_entries( {
+ 'filepath': current_buffer_file,
+ 'line_num': 1,
+ 'column_num': 6,
+ 'file_data': has_entries( {
+ current_buffer_file: has_entries( {
+ 'contents': 'current_buffer_contents\n',
+ 'filetypes': [ 'some_filetype' ]
+ } ),
+ modified_buffer_file: has_entries( {
+ 'contents': 'modified_buffer_contents\n',
+ 'filetypes': [ 'some_filetype' ]
+ } )
+ } ),
+ 'event_name': 'BufferVisit'
+ } ),
+ 'event_notification'
+ )
+ )
+
+
+ @YouCompleteMeInstance()
+ def test_EventNotification_BufferUnload_BuildRequestForDeletedAndUnsavedBuffers( # noqa
+ self, ycm ):
+ current_buffer_file = os.path.realpath( 'current_βuffer' )
+ current_buffer = VimBuffer( name = current_buffer_file,
+ number = 1,
+ contents = [ 'current_buffer_contents' ],
+ filetype = 'some_filetype',
+ modified = True )
+
+ deleted_buffer_file = os.path.realpath( 'deleted_βuffer' )
+ deleted_buffer = VimBuffer( name = deleted_buffer_file,
+ number = 2,
+ contents = [ 'deleted_buffer_contents' ],
+ filetype = 'some_filetype',
+ modified = False )
+
+ with patch( 'ycm.client.event_notification.EventNotification.'
+ 'PostDataToHandlerAsync' ) as post_data_to_handler_async:
+ with MockVimBuffers( [ current_buffer, deleted_buffer ],
+ [ current_buffer ] ):
+ ycm.OnBufferUnload( deleted_buffer.number )
assert_that(
# Positional arguments passed to PostDataToHandlerAsync.
post_data_to_handler_async.call_args[ 0 ],
contains_exactly(
has_entries( {
- 'filepath': current_buffer_file,
+ 'filepath': deleted_buffer_file,
'line_num': 1,
- 'column_num': 6,
+ 'column_num': 1,
'file_data': has_entries( {
current_buffer_file: has_entries( {
'contents': 'current_buffer_contents\n',
'filetypes': [ 'some_filetype' ]
} ),
- modified_buffer_file: has_entries( {
- 'contents': 'modified_buffer_contents\n',
+ deleted_buffer_file: has_entries( {
+ 'contents': 'deleted_buffer_contents\n',
'filetypes': [ 'some_filetype' ]
} )
} ),
- 'event_name': 'BufferVisit'
+ 'event_name': 'BufferUnload'
} ),
'event_notification'
)
)
-@YouCompleteMeInstance()
-def EventNotification_BufferUnload_BuildRequestForDeletedAndUnsavedBuffers_test(
- ycm ):
- current_buffer_file = os.path.realpath( 'current_βuffer' )
- current_buffer = VimBuffer( name = current_buffer_file,
- number = 1,
- contents = [ 'current_buffer_contents' ],
- filetype = 'some_filetype',
- modified = True )
-
- deleted_buffer_file = os.path.realpath( 'deleted_βuffer' )
- deleted_buffer = VimBuffer( name = deleted_buffer_file,
- number = 2,
- contents = [ 'deleted_buffer_contents' ],
- filetype = 'some_filetype',
- modified = False )
-
- with patch( 'ycm.client.event_notification.EventNotification.'
- 'PostDataToHandlerAsync' ) as post_data_to_handler_async:
- with MockVimBuffers( [ current_buffer, deleted_buffer ],
- [ current_buffer ] ):
- ycm.OnBufferUnload( deleted_buffer.number )
-
- assert_that(
- # Positional arguments passed to PostDataToHandlerAsync.
- post_data_to_handler_async.call_args[ 0 ],
- contains_exactly(
- has_entries( {
- 'filepath': deleted_buffer_file,
- 'line_num': 1,
- 'column_num': 1,
- 'file_data': has_entries( {
- current_buffer_file: has_entries( {
- 'contents': 'current_buffer_contents\n',
- 'filetypes': [ 'some_filetype' ]
- } ),
- deleted_buffer_file: has_entries( {
- 'contents': 'deleted_buffer_contents\n',
- 'filetypes': [ 'some_filetype' ]
- } )
- } ),
- 'event_name': 'BufferUnload'
- } ),
- 'event_notification'
- )
- )
-
-
-@patch( 'ycm.vimsupport.CaptureVimCommand', return_value = """
+ @patch( 'ycm.vimsupport.CaptureVimCommand', return_value = """
fooGroup xxx foo bar
links to Statement""" )
-@YouCompleteMeInstance( { 'g:ycm_seed_identifiers_with_syntax': 1 } )
-def EventNotification_FileReadyToParse_SyntaxKeywords_SeedWithCache_test(
- capture_vim_command, ycm ):
+ @YouCompleteMeInstance( { 'g:ycm_seed_identifiers_with_syntax': 1 } )
+ def test_EventNotification_FileReadyToParse_SyntaxKeywords_SeedWithCache(
+ self, ycm, *args ):
- current_buffer = VimBuffer( name = 'current_buffer',
- filetype = 'some_filetype' )
+ current_buffer = VimBuffer( name = 'current_buffer',
+ filetype = 'some_filetype' )
- with patch( 'ycm.client.event_notification.EventNotification.'
- 'PostDataToHandlerAsync' ) as post_data_to_handler_async:
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- ycm.OnFileReadyToParse()
- assert_that(
- # Positional arguments passed to PostDataToHandlerAsync.
- post_data_to_handler_async.call_args[ 0 ],
- contains_exactly(
- has_entry( 'syntax_keywords', has_items( 'foo', 'bar' ) ),
- 'event_notification'
+ with patch( 'ycm.client.event_notification.EventNotification.'
+ 'PostDataToHandlerAsync' ) as post_data_to_handler_async:
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ ycm.OnFileReadyToParse()
+ assert_that(
+ # Positional arguments passed to PostDataToHandlerAsync.
+ post_data_to_handler_async.call_args[ 0 ],
+ contains_exactly(
+ has_entry( 'syntax_keywords', has_items( 'foo', 'bar' ) ),
+ 'event_notification'
+ )
)
- )
- # Do not send again syntax keywords in subsequent requests.
- ycm.OnFileReadyToParse()
- assert_that(
- # Positional arguments passed to PostDataToHandlerAsync.
- post_data_to_handler_async.call_args[ 0 ],
- contains_exactly(
- is_not( has_key( 'syntax_keywords' ) ),
- 'event_notification'
+ # Do not send again syntax keywords in subsequent requests.
+ ycm.OnFileReadyToParse()
+ assert_that(
+ # Positional arguments passed to PostDataToHandlerAsync.
+ post_data_to_handler_async.call_args[ 0 ],
+ contains_exactly(
+ is_not( has_key( 'syntax_keywords' ) ),
+ 'event_notification'
+ )
)
- )
-@patch( 'ycm.vimsupport.CaptureVimCommand', return_value = """
+ @patch( 'ycm.vimsupport.CaptureVimCommand', return_value = """
fooGroup xxx foo bar
links to Statement""" )
-@YouCompleteMeInstance( { 'g:ycm_seed_identifiers_with_syntax': 1 } )
-def EventNotification_FileReadyToParse_SyntaxKeywords_ClearCacheIfRestart_test(
- capture_vim_command, ycm ):
+ @YouCompleteMeInstance( { 'g:ycm_seed_identifiers_with_syntax': 1 } )
+ def test_EventNotification_FileReadyToParse_SyntaxKeywords_ClearCacheIfRestart( # noqa
+ self, ycm, *args ):
- current_buffer = VimBuffer( name = 'current_buffer',
- filetype = 'some_filetype' )
+ current_buffer = VimBuffer( name = 'current_buffer',
+ filetype = 'some_filetype' )
- with patch( 'ycm.client.event_notification.EventNotification.'
- 'PostDataToHandlerAsync' ) as post_data_to_handler_async:
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- ycm.OnFileReadyToParse()
- assert_that(
- # Positional arguments passed to PostDataToHandlerAsync.
- post_data_to_handler_async.call_args[ 0 ],
- contains_exactly(
- has_entry( 'syntax_keywords', has_items( 'foo', 'bar' ) ),
- 'event_notification'
+ with patch( 'ycm.client.event_notification.EventNotification.'
+ 'PostDataToHandlerAsync' ) as post_data_to_handler_async:
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ ycm.OnFileReadyToParse()
+ assert_that(
+ # Positional arguments passed to PostDataToHandlerAsync.
+ post_data_to_handler_async.call_args[ 0 ],
+ contains_exactly(
+ has_entry( 'syntax_keywords', has_items( 'foo', 'bar' ) ),
+ 'event_notification'
+ )
)
- )
- # Send again the syntax keywords after restarting the server.
- ycm.RestartServer()
- WaitUntilReady()
- ycm.OnFileReadyToParse()
- assert_that(
- # Positional arguments passed to PostDataToHandlerAsync.
- post_data_to_handler_async.call_args[ 0 ],
- contains_exactly(
- has_entry( 'syntax_keywords', has_items( 'foo', 'bar' ) ),
- 'event_notification'
+ # Send again the syntax keywords after restarting the server.
+ ycm.RestartServer()
+ WaitUntilReady()
+ ycm.OnFileReadyToParse()
+ assert_that(
+ # Positional arguments passed to PostDataToHandlerAsync.
+ post_data_to_handler_async.call_args[ 0 ],
+ contains_exactly(
+ has_entry( 'syntax_keywords', has_items( 'foo', 'bar' ) ),
+ 'event_notification'
+ )
)
- )
diff --git a/python/ycm/tests/omni_completer_test.py b/python/ycm/tests/omni_completer_test.py
index cebe395bc2..b2428e5704 100644
--- a/python/ycm/tests/omni_completer_test.py
+++ b/python/ycm/tests/omni_completer_test.py
@@ -18,7 +18,7 @@
# along with YouCompleteMe. If not, see .
from hamcrest import assert_that, contains_exactly, empty, has_entries
-import pytest
+from unittest import TestCase
from ycm.tests.test_utils import MockVimBuffers, MockVimModule, VimBuffer
MockVimModule()
@@ -32,556 +32,537 @@
}
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_Cache_List_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 5
- return [ 'a', 'b', 'cdef' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 5 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [
- { 'word': 'a', 'equal': 1 },
- { 'word': 'b', 'equal': 1 },
- { 'word': 'cdef', 'equal': 1 }
- ],
- 'completion_start_column': 6
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_Cache_ListFilter_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 5
- return [ 'a', 'b', 'cdef' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.t' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': empty(),
- 'completion_start_column': 6
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_NoCache_List_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 5
- return [ 'a', 'b', 'cdef' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 5 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [
- { 'word': 'a', 'equal': 1 },
- { 'word': 'b', 'equal': 1 },
- { 'word': 'cdef', 'equal': 1 }
- ],
- 'completion_start_column': 6
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_NoCache_ListFilter_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 5
- return [ 'a', 'b', 'cdef' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.t' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
- ycm.SendCompletionRequest()
- # Actual result is that the results are not filtered, as we expect the
- # omnifunc or vim itself to do this filtering.
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [
- { 'word': 'a', 'equal': 1 },
- { 'word': 'b', 'equal': 1 },
- { 'word': 'cdef', 'equal': 1 }
- ],
- 'completion_start_column': 6
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_NoCache_UseFindStart_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 0
- return [ 'a', 'b', 'cdef' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.t' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
- ycm.SendCompletionRequest()
- # Actual result is that the results are not filtered, as we expect the
- # omnifunc or vim itself to do this filtering.
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [
- { 'word': 'a', 'equal': 1 },
- { 'word': 'b', 'equal': 1 },
- { 'word': 'cdef', 'equal': 1 }
- ],
- 'completion_start_column': 1
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_Cache_UseFindStart_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 0
- return [ 'a', 'b', 'cdef' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.t' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
- ycm.SendCompletionRequest()
- # There are no results because the query 'test.t' doesn't match any
- # candidate (and cache_omnifunc=1, so we FilterAndSortCandidates).
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': empty(),
- 'completion_start_column': 1
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_Cache_Object_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 5
- return { 'words': [ 'a', 'b', 'CDtEF' ] }
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.t' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [ { 'word': 'CDtEF', 'equal': 1 } ],
- 'completion_start_column': 6
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_Cache_ObjectList_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 5
- return [
- {
- 'word': 'a',
- 'abbr': 'ABBR',
- 'menu': 'MENU',
- 'info': 'INFO',
- 'kind': 'K'
- },
- {
- 'word': 'test',
- 'abbr': 'ABBRTEST',
- 'menu': 'MENUTEST',
- 'info': 'INFOTEST',
- 'kind': 'T'
- }
- ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.tt' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': contains_exactly( {
- 'word' : 'test',
- 'abbr' : 'ABBRTEST',
- 'menu' : 'MENUTEST',
- 'info' : 'INFOTEST',
- 'kind' : 'T',
- 'equal': 1
- } ),
- 'completion_start_column': 6
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_NoCache_ObjectList_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 5
- return [
- {
- 'word': 'a',
- 'abbr': 'ABBR',
- 'menu': 'MENU',
- 'info': 'INFO',
- 'kind': 'K'
- },
- {
- 'word': 'test',
- 'abbr': 'ABBRTEST',
- 'menu': 'MENUTEST',
- 'info': 'INFOTEST',
- 'kind': 'T'
- }
- ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.tt' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
- ycm.SendCompletionRequest()
- # We don't filter the result - we expect the omnifunc to do that
- # based on the query we supplied (Note: that means no fuzzy matching!).
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [ {
- 'word' : 'a',
- 'abbr' : 'ABBR',
- 'menu' : 'MENU',
- 'info' : 'INFO',
- 'kind' : 'K',
- 'equal': 1
- }, {
- 'word' : 'test',
- 'abbr' : 'ABBRTEST',
- 'menu' : 'MENUTEST',
- 'info' : 'INFOTEST',
- 'kind' : 'T',
- 'equal': 1
- } ],
- 'completion_start_column': 6
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_Cache_ObjectListObject_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 5
- return { 'words': [
- {
- 'word': 'a',
- 'abbr': 'ABBR',
- 'menu': 'MENU',
- 'info': 'INFO',
- 'kind': 'K'
- },
- {
- 'word': 'test',
- 'abbr': 'ABBRTEST',
- 'menu': 'MENUTEST',
- 'info': 'INFOTEST',
- 'kind': 'T'
- }
- ] }
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.tt' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [ {
- 'word' : 'test',
- 'abbr' : 'ABBRTEST',
- 'menu' : 'MENUTEST',
- 'info' : 'INFOTEST',
- 'kind' : 'T',
- 'equal': 1
- } ],
- 'completion_start_column': 6
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_NoCache_ObjectListObject_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 5
- return { 'words': [
- {
- 'word': 'a',
- 'abbr': 'ABBR',
- 'menu': 'MENU',
- 'info': 'INFO',
- 'kind': 'K'
- },
- {
- 'word': 'test',
- 'abbr': 'ABBRTEST',
- 'menu': 'MENUTEST',
- 'info': 'INFOTEST',
- 'kind': 'T'
- }
- ] }
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.tt' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
- ycm.SendCompletionRequest()
- # No FilterAndSortCandidates for cache_omnifunc=0 (we expect the omnifunc
- # to do the filtering?)
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [ {
- 'word' : 'a',
- 'abbr' : 'ABBR',
- 'menu' : 'MENU',
- 'info' : 'INFO',
- 'kind' : 'K',
- 'equal': 1
- }, {
- 'word' : 'test',
- 'abbr' : 'ABBRTEST',
- 'menu' : 'MENUTEST',
- 'info' : 'INFOTEST',
- 'kind' : 'T',
- 'equal': 1
- } ],
- 'completion_start_column': 6
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_Cache_List_Unicode_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 12
- return [ '†est', 'å_unicode_identifier', 'πππππππ yummy πie' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ '†åsty_π.' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 12 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [
- { 'word': 'å_unicode_identifier', 'equal': 1 },
- { 'word': 'πππππππ yummy πie', 'equal': 1 },
- { 'word': '†est', 'equal': 1 }
- ],
- 'completion_start_column': 13
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_NoCache_List_Unicode_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 12
- return [ '†est', 'å_unicode_identifier', 'πππππππ yummy πie' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ '†åsty_π.' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 12 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [
- { 'word': '†est', 'equal': 1 },
- { 'word': 'å_unicode_identifier', 'equal': 1 },
- { 'word': 'πππππππ yummy πie', 'equal': 1 }
- ],
- 'completion_start_column': 13
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_Cache_List_Filter_Unicode_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 12
- return [ '†est', 'å_unicode_identifier', 'πππππππ yummy πie' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ '†åsty_π.ππ' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 17 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [ { 'word': 'πππππππ yummy πie', 'equal': 1 } ],
- 'completion_start_column': 13
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_NoCache_List_Filter_Unicode_test( ycm ):
+def StartColumnCompliance( ycm,
+ omnifunc_start_column,
+ ycm_completions,
+ ycm_start_column ):
def Omnifunc( findstart, base ):
if findstart:
- return 12
- return [ 'πππππππ yummy πie' ]
+ return omnifunc_start_column
+ return [ 'foo' ]
current_buffer = VimBuffer( 'buffer',
- contents = [ '†åsty_π.ππ' ],
+ contents = [ 'fo' ],
filetype = FILETYPE,
omnifunc = Omnifunc )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 17 ) ):
- ycm.SendCompletionRequest()
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 2 ) ):
+ ycm.SendCompletionRequest( force_semantic = True )
+ r = ycm.GetCompletionResponse()
assert_that(
- ycm.GetCompletionResponse(),
+ r,
has_entries( {
- 'completions': [ { 'word': 'πππππππ yummy πie', 'equal': 1 } ],
- 'completion_start_column': 13
+ 'completions': ycm_completions,
+ 'completion_start_column': ycm_start_column
} )
)
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_Cache_ObjectList_Unicode_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 12
- return [
- {
- 'word': 'ålpha∫et',
- 'abbr': 'å∫∫®',
- 'menu': 'µ´~¨á',
- 'info': '^~fo',
- 'kind': '˚'
- },
- {
- 'word': 'π†´ß†π',
- 'abbr': 'ÅııÂʉÍÊ',
- 'menu': '˜‰ˆËʉÍÊ',
- 'info': 'ȈÏØʉÍÊ',
- 'kind': 'Ê'
- }
- ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ '†åsty_π.ππ' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 17 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [ {
- 'word' : 'π†´ß†π',
- 'abbr' : 'ÅııÂʉÍÊ',
- 'menu' : '˜‰ˆËʉÍÊ',
- 'info' : 'ȈÏØʉÍÊ',
- 'kind' : 'Ê',
- 'equal': 1
- } ],
- 'completion_start_column': 13
- } )
- )
+class OmniCompleterTest( TestCase ):
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_Cache_List( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 5
+ return [ 'a', 'b', 'cdef' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 5 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [
+ { 'word': 'a', 'equal': 1 },
+ { 'word': 'b', 'equal': 1 },
+ { 'word': 'cdef', 'equal': 1 }
+ ],
+ 'completion_start_column': 6
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_Cache_ListFilter( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 5
+ return [ 'a', 'b', 'cdef' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.t' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': empty(),
+ 'completion_start_column': 6
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_NoCache_List( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 5
+ return [ 'a', 'b', 'cdef' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 5 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [
+ { 'word': 'a', 'equal': 1 },
+ { 'word': 'b', 'equal': 1 },
+ { 'word': 'cdef', 'equal': 1 }
+ ],
+ 'completion_start_column': 6
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_NoCache_ListFilter( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 5
+ return [ 'a', 'b', 'cdef' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.t' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
+ ycm.SendCompletionRequest()
+ # Actual result is that the results are not filtered, as we expect the
+ # omnifunc or vim itself to do this filtering.
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [
+ { 'word': 'a', 'equal': 1 },
+ { 'word': 'b', 'equal': 1 },
+ { 'word': 'cdef', 'equal': 1 }
+ ],
+ 'completion_start_column': 6
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_NoCache_UseFindStart( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 0
+ return [ 'a', 'b', 'cdef' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.t' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
+ ycm.SendCompletionRequest()
+ # Actual result is that the results are not filtered, as we expect the
+ # omnifunc or vim itself to do this filtering.
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [
+ { 'word': 'a', 'equal': 1 },
+ { 'word': 'b', 'equal': 1 },
+ { 'word': 'cdef', 'equal': 1 }
+ ],
+ 'completion_start_column': 1
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_Cache_UseFindStart( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 0
+ return [ 'a', 'b', 'cdef' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.t' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
+ ycm.SendCompletionRequest()
+ # There are no results because the query 'test.t' doesn't match any
+ # candidate (and cache_omnifunc=1, so we FilterAndSortCandidates).
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': empty(),
+ 'completion_start_column': 1
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_Cache_Object( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 5
+ return { 'words': [ 'a', 'b', 'CDtEF' ] }
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.t' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [ { 'word': 'CDtEF', 'equal': 1 } ],
+ 'completion_start_column': 6
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_Cache_ObjectList( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 5
+ return [
+ {
+ 'word': 'a',
+ 'abbr': 'ABBR',
+ 'menu': 'MENU',
+ 'info': 'INFO',
+ 'kind': 'K'
+ },
+ {
+ 'word': 'test',
+ 'abbr': 'ABBRTEST',
+ 'menu': 'MENUTEST',
+ 'info': 'INFOTEST',
+ 'kind': 'T'
+ }
+ ]
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.tt' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': contains_exactly( {
+ 'word' : 'test',
+ 'abbr' : 'ABBRTEST',
+ 'menu' : 'MENUTEST',
+ 'info' : 'INFOTEST',
+ 'kind' : 'T',
+ 'equal': 1
+ } ),
+ 'completion_start_column': 6
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_NoCache_ObjectList( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 5
+ return [
+ {
+ 'word': 'a',
+ 'abbr': 'ABBR',
+ 'menu': 'MENU',
+ 'info': 'INFO',
+ 'kind': 'K'
+ },
+ {
+ 'word': 'test',
+ 'abbr': 'ABBRTEST',
+ 'menu': 'MENUTEST',
+ 'info': 'INFOTEST',
+ 'kind': 'T'
+ }
+ ]
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_Cache_ObjectListObject_Unicode_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 12
- return {
- 'words': [
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.tt' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
+ ycm.SendCompletionRequest()
+ # We don't filter the result - we expect the omnifunc to do that
+ # based on the query we supplied (Note: that means no fuzzy matching!).
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [ {
+ 'word' : 'a',
+ 'abbr' : 'ABBR',
+ 'menu' : 'MENU',
+ 'info' : 'INFO',
+ 'kind' : 'K',
+ 'equal': 1
+ }, {
+ 'word' : 'test',
+ 'abbr' : 'ABBRTEST',
+ 'menu' : 'MENUTEST',
+ 'info' : 'INFOTEST',
+ 'kind' : 'T',
+ 'equal': 1
+ } ],
+ 'completion_start_column': 6
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_Cache_ObjectListObject( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 5
+ return { 'words': [
+ {
+ 'word': 'a',
+ 'abbr': 'ABBR',
+ 'menu': 'MENU',
+ 'info': 'INFO',
+ 'kind': 'K'
+ },
+ {
+ 'word': 'test',
+ 'abbr': 'ABBRTEST',
+ 'menu': 'MENUTEST',
+ 'info': 'INFOTEST',
+ 'kind': 'T'
+ }
+ ] }
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.tt' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [ {
+ 'word' : 'test',
+ 'abbr' : 'ABBRTEST',
+ 'menu' : 'MENUTEST',
+ 'info' : 'INFOTEST',
+ 'kind' : 'T',
+ 'equal': 1
+ } ],
+ 'completion_start_column': 6
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_NoCache_ObjectListObject( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 5
+ return { 'words': [
+ {
+ 'word': 'a',
+ 'abbr': 'ABBR',
+ 'menu': 'MENU',
+ 'info': 'INFO',
+ 'kind': 'K'
+ },
+ {
+ 'word': 'test',
+ 'abbr': 'ABBRTEST',
+ 'menu': 'MENUTEST',
+ 'info': 'INFOTEST',
+ 'kind': 'T'
+ }
+ ] }
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.tt' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
+ ycm.SendCompletionRequest()
+ # No FilterAndSortCandidates for cache_omnifunc=0 (we expect the omnifunc
+ # to do the filtering?)
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [ {
+ 'word' : 'a',
+ 'abbr' : 'ABBR',
+ 'menu' : 'MENU',
+ 'info' : 'INFO',
+ 'kind' : 'K',
+ 'equal': 1
+ }, {
+ 'word' : 'test',
+ 'abbr' : 'ABBRTEST',
+ 'menu' : 'MENUTEST',
+ 'info' : 'INFOTEST',
+ 'kind' : 'T',
+ 'equal': 1
+ } ],
+ 'completion_start_column': 6
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_Cache_List_Unicode( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 12
+ return [ '†est', 'å_unicode_identifier', 'πππππππ yummy πie' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ '†åsty_π.' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 12 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [
+ { 'word': 'å_unicode_identifier', 'equal': 1 },
+ { 'word': 'πππππππ yummy πie', 'equal': 1 },
+ { 'word': '†est', 'equal': 1 }
+ ],
+ 'completion_start_column': 13
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_NoCache_List_Unicode( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 12
+ return [ '†est', 'å_unicode_identifier', 'πππππππ yummy πie' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ '†åsty_π.' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 12 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [
+ { 'word': '†est', 'equal': 1 },
+ { 'word': 'å_unicode_identifier', 'equal': 1 },
+ { 'word': 'πππππππ yummy πie', 'equal': 1 }
+ ],
+ 'completion_start_column': 13
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_Cache_List_Filter_Unicode( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 12
+ return [ '†est', 'å_unicode_identifier', 'πππππππ yummy πie' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ '†åsty_π.ππ' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 17 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [ { 'word': 'πππππππ yummy πie', 'equal': 1 } ],
+ 'completion_start_column': 13
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_NoCache_List_Filter_Unicode(
+ self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 12
+ return [ 'πππππππ yummy πie' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ '†åsty_π.ππ' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 17 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [ { 'word': 'πππππππ yummy πie', 'equal': 1 } ],
+ 'completion_start_column': 13
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_Cache_ObjectList_Unicode( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 12
+ return [
{
'word': 'ålpha∫et',
'abbr': 'å∫∫®',
@@ -595,352 +576,378 @@ def Omnifunc( findstart, base ):
'menu': '˜‰ˆËʉÍÊ',
'info': 'ȈÏØʉÍÊ',
'kind': 'Ê'
- },
- {
- 'word': 'test',
- 'abbr': 'ÅııÂʉÍÊ',
- 'menu': '˜‰ˆËʉÍÊ',
- 'info': 'ȈÏØʉÍÊ',
- 'kind': 'Ê'
}
]
- }
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ '†åsty_π.t' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 13 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': contains_exactly( {
- 'word' : 'test',
- 'abbr' : 'ÅııÂʉÍÊ',
- 'menu' : '˜‰ˆËʉÍÊ',
- 'info' : 'ȈÏØʉÍÊ',
- 'kind' : 'Ê',
- 'equal': 1
- }, {
- 'word' : 'ålpha∫et',
- 'abbr' : 'å∫∫®',
- 'menu' : 'µ´~¨á',
- 'info' : '^~fo',
- 'kind' : '˚',
- 'equal': 1
- } ),
- 'completion_start_column': 13
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_RestoreCursorPositionAfterOmnifuncCall_test(
- ycm ):
-
- # This omnifunc moves the cursor to the test definition like
- # ccomplete#Complete would.
- def Omnifunc( findstart, base ):
- vimsupport.SetCurrentLineAndColumn( 0, 0 )
- if findstart:
- return 5
- return [ 'length' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'String test',
- '',
- 'test.' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 3, 5 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- vimsupport.CurrentLineAndColumn(),
- contains_exactly( 2, 5 )
- )
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [ { 'word': 'length', 'equal': 1 } ],
- 'completion_start_column': 6
- } )
- )
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ '†åsty_π.ππ' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 17 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [ {
+ 'word' : 'π†´ß†π',
+ 'abbr' : 'ÅııÂʉÍÊ',
+ 'menu' : '˜‰ˆËʉÍÊ',
+ 'info' : 'ȈÏØʉÍÊ',
+ 'kind' : 'Ê',
+ 'equal': 1
+ } ],
+ 'completion_start_column': 13
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_Cache_ObjectListObject_Unicode(
+ self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 12
+ return {
+ 'words': [
+ {
+ 'word': 'ålpha∫et',
+ 'abbr': 'å∫∫®',
+ 'menu': 'µ´~¨á',
+ 'info': '^~fo',
+ 'kind': '˚'
+ },
+ {
+ 'word': 'π†´ß†π',
+ 'abbr': 'ÅııÂʉÍÊ',
+ 'menu': '˜‰ˆËʉÍÊ',
+ 'info': 'ȈÏØʉÍÊ',
+ 'kind': 'Ê'
+ },
+ {
+ 'word': 'test',
+ 'abbr': 'ÅııÂʉÍÊ',
+ 'menu': '˜‰ˆËʉÍÊ',
+ 'info': 'ȈÏØʉÍÊ',
+ 'kind': 'Ê'
+ }
+ ]
+ }
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_MoveCursorPositionAtStartColumn_test( ycm ):
- # This omnifunc relies on the cursor being moved at the start column when
- # called the second time like LanguageClient#complete from the
- # LanguageClient-neovim plugin.
- def Omnifunc( findstart, base ):
- if findstart:
- return 5
- if vimsupport.CurrentColumn() == 5:
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ '†åsty_π.t' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 13 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': contains_exactly( {
+ 'word' : 'test',
+ 'abbr' : 'ÅııÂʉÍÊ',
+ 'menu' : '˜‰ˆËʉÍÊ',
+ 'info' : 'ȈÏØʉÍÊ',
+ 'kind' : 'Ê',
+ 'equal': 1
+ }, {
+ 'word' : 'ålpha∫et',
+ 'abbr' : 'å∫∫®',
+ 'menu' : 'µ´~¨á',
+ 'info' : '^~fo',
+ 'kind' : '˚',
+ 'equal': 1
+ } ),
+ 'completion_start_column': 13
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_RestoreCursorPositionAfterOmnifuncCall(
+ self, ycm ):
+
+ # This omnifunc moves the cursor to the test definition like
+ # ccomplete#Complete would.
+ def Omnifunc( findstart, base ):
+ vimsupport.SetCurrentLineAndColumn( 0, 0 )
+ if findstart:
+ return 5
return [ 'length' ]
- return []
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'String test',
- '',
- 'test.le' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 3, 7 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- vimsupport.CurrentLineAndColumn(),
- contains_exactly( 2, 7 )
- )
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [ { 'word': 'length', 'equal': 1 } ],
- 'completion_start_column': 6
- } )
- )
-
-
-def StartColumnCompliance( ycm,
- omnifunc_start_column,
- ycm_completions,
- ycm_start_column ):
- def Omnifunc( findstart, base ):
- if findstart:
- return omnifunc_start_column
- return [ 'foo' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'fo' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 2 ) ):
- ycm.SendCompletionRequest( force_semantic = True )
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': ycm_completions,
- 'completion_start_column': ycm_start_column
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1 } )
-@pytest.mark.parametrize(
- 'omnifunc_start_column,ycm_completions,ycm_start_column', [
- [ -4, [ { 'word': 'foo', 'equal': 1 } ], 3 ],
- [ -3, [], 1 ],
- [ -2, [], 1 ],
- [ -1, [ { 'word': 'foo', 'equal': 1 } ], 3 ],
- [ 0, [ { 'word': 'foo', 'equal': 1 } ], 1 ],
- [ 1, [ { 'word': 'foo', 'equal': 1 } ], 2 ],
- [ 2, [ { 'word': 'foo', 'equal': 1 } ], 3 ],
- [ 3, [ { 'word': 'foo', 'equal': 1 } ], 3 ]
- ] )
-def OmniCompleter_GetCompletions_StartColumnCompliance_test(
- ycm,
- omnifunc_start_column,
- ycm_completions,
- ycm_start_column ):
- StartColumnCompliance( ycm,
- omnifunc_start_column,
- ycm_completions,
- ycm_start_column )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_NoCache_NoSemanticTrigger_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 0
- return [ 'test' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'te' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 3 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': empty(),
- 'completion_start_column': 1
- } )
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_NoCache_ForceSemantic_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 0
- return [ 'test' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'te' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 3 ) ):
- ycm.SendCompletionRequest( force_semantic = True )
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [ { 'word': 'test', 'equal': 1 } ],
- 'completion_start_column': 1
- } )
- )
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'String test',
+ '',
+ 'test.' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 3, 5 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ vimsupport.CurrentLineAndColumn(),
+ contains_exactly( 2, 5 )
+ )
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [ { 'word': 'length', 'equal': 1 } ],
+ 'completion_start_column': 6
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_MoveCursorPositionAtStartColumn(
+ self, ycm ):
+ # This omnifunc relies on the cursor being moved at the start column when
+ # called the second time like LanguageClient#complete from the
+ # LanguageClient-neovim plugin.
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 5
+ if vimsupport.CurrentColumn() == 5:
+ return [ 'length' ]
+ return []
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'String test',
+ '',
+ 'test.le' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 3, 7 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ vimsupport.CurrentLineAndColumn(),
+ contains_exactly( 2, 7 )
+ )
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [ { 'word': 'length', 'equal': 1 } ],
+ 'completion_start_column': 6
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0, } )
+ def test_OmniCompleter_GetCompletions_StartColumnCompliance( self, ycm ):
+ for omnifunc_start_column, ycm_completions, ycm_start_column in [
+ [ -4, [ { 'word': 'foo', 'equal': 1 } ], 3 ],
+ [ -3, [], 1 ],
+ [ -2, [], 1 ],
+ [ -1, [ { 'word': 'foo', 'equal': 1 } ], 3 ],
+ [ 0, [ { 'word': 'foo', 'equal': 1 } ], 1 ],
+ [ 1, [ { 'word': 'foo', 'equal': 1 } ], 2 ],
+ [ 2, [ { 'word': 'foo', 'equal': 1 } ], 3 ],
+ [ 3, [ { 'word': 'foo', 'equal': 1 } ], 3 ]
+ ]:
+ with self.subTest( omnifunc_start_column = omnifunc_start_column,
+ ycm_completions = ycm_completions,
+ ycm_start_column = ycm_start_column ):
+ StartColumnCompliance( ycm,
+ omnifunc_start_column,
+ ycm_completions,
+ ycm_start_column )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_NoCache_NoSemanticTrigger( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 0
+ return [ 'test' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'te' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 3 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': empty(),
+ 'completion_start_column': 1
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 0,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_NoCache_ForceSemantic( self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 0
+ return [ 'test' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'te' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 3 ) ):
+ ycm.SendCompletionRequest( force_semantic = True )
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [ { 'word': 'test', 'equal': 1 } ],
+ 'completion_start_column': 1
+ } )
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_ConvertStringsToDictionaries(
+ self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 5
+ return [
+ { 'word': 'a' },
+ 'b'
+ ]
-@YouCompleteMeInstance( { 'g:ycm_cache_omnifunc': 1,
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_ConvertStringsToDictionaries_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 5
- return [
- { 'word': 'a' },
- 'b'
- ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [
- { 'word': 'a', 'equal': 1 },
- { 'word': 'b', 'equal': 1 }
- ],
- 'completion_start_column': 6
- } )
- )
-
-
-@YouCompleteMeInstance( {
- 'g:ycm_cache_omnifunc': 0,
- 'g:ycm_filetype_specific_completion_to_disable': { FILETYPE: 1 },
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_FiletypeDisabled_SemanticTrigger_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 5
- return [ 'a', 'b', 'cdef' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': empty(),
- 'completion_start_column': 6
- } )
- )
-
-
-@YouCompleteMeInstance( {
- 'g:ycm_cache_omnifunc': 0,
- 'g:ycm_filetype_specific_completion_to_disable': { '*': 1 },
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_AllFiletypesDisabled_SemanticTrigger_test(
- ycm ):
-
- def Omnifunc( findstart, base ):
- if findstart:
- return 5
- return [ 'a', 'b', 'cdef' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
- ycm.SendCompletionRequest()
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': empty(),
- 'completion_start_column': 6
- } )
- )
-
-
-@YouCompleteMeInstance( {
- 'g:ycm_cache_omnifunc': 0,
- 'g:ycm_filetype_specific_completion_to_disable': { FILETYPE: 1 },
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_FiletypeDisabled_ForceSemantic_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 5
- return [ 'a', 'b', 'cdef' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
- ycm.SendCompletionRequest( force_semantic = True )
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [
- { 'word': 'a', 'equal': 1 },
- { 'word': 'b', 'equal': 1 },
- { 'word': 'cdef', 'equal': 1 }
- ],
- 'completion_start_column': 6
- } )
- )
-
-
-@YouCompleteMeInstance( {
- 'g:ycm_cache_omnifunc': 0,
- 'g:ycm_filetype_specific_completion_to_disable': { '*': 1 },
- 'g:ycm_semantic_triggers': TRIGGERS } )
-def OmniCompleter_GetCompletions_AllFiletypesDisabled_ForceSemantic_test( ycm ):
- def Omnifunc( findstart, base ):
- if findstart:
- return 5
- return [ 'a', 'b', 'cdef' ]
-
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'test.' ],
- filetype = FILETYPE,
- omnifunc = Omnifunc )
-
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
- ycm.SendCompletionRequest( force_semantic = True )
- assert_that(
- ycm.GetCompletionResponse(),
- has_entries( {
- 'completions': [
- { 'word': 'a', 'equal': 1 },
- { 'word': 'b', 'equal': 1 },
- { 'word': 'cdef', 'equal': 1 }
- ],
- 'completion_start_column': 6
- } )
- )
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 7 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [
+ { 'word': 'a', 'equal': 1 },
+ { 'word': 'b', 'equal': 1 }
+ ],
+ 'completion_start_column': 6
+ } )
+ )
+
+
+ @YouCompleteMeInstance( {
+ 'g:ycm_cache_omnifunc': 0,
+ 'g:ycm_filetype_specific_completion_to_disable': { FILETYPE: 1 },
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_FiletypeDisabled_SemanticTrigger(
+ self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 5
+ return [ 'a', 'b', 'cdef' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': empty(),
+ 'completion_start_column': 6
+ } )
+ )
+
+
+ @YouCompleteMeInstance( {
+ 'g:ycm_cache_omnifunc': 0,
+ 'g:ycm_filetype_specific_completion_to_disable': { '*': 1 },
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_AllFiletypesDisabled_SemanticTrigger(
+ self, ycm ):
+
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 5
+ return [ 'a', 'b', 'cdef' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
+ ycm.SendCompletionRequest()
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': empty(),
+ 'completion_start_column': 6
+ } )
+ )
+
+
+ @YouCompleteMeInstance( {
+ 'g:ycm_cache_omnifunc': 0,
+ 'g:ycm_filetype_specific_completion_to_disable': { FILETYPE: 1 },
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_FiletypeDisabled_ForceSemantic(
+ self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 5
+ return [ 'a', 'b', 'cdef' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
+ ycm.SendCompletionRequest( force_semantic = True )
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [
+ { 'word': 'a', 'equal': 1 },
+ { 'word': 'b', 'equal': 1 },
+ { 'word': 'cdef', 'equal': 1 }
+ ],
+ 'completion_start_column': 6
+ } )
+ )
+
+
+ @YouCompleteMeInstance( {
+ 'g:ycm_cache_omnifunc': 0,
+ 'g:ycm_filetype_specific_completion_to_disable': { '*': 1 },
+ 'g:ycm_semantic_triggers': TRIGGERS } )
+ def test_OmniCompleter_GetCompletions_AllFiletypesDisabled_ForceSemantic(
+ self, ycm ):
+ def Omnifunc( findstart, base ):
+ if findstart:
+ return 5
+ return [ 'a', 'b', 'cdef' ]
+
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'test.' ],
+ filetype = FILETYPE,
+ omnifunc = Omnifunc )
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 6 ) ):
+ ycm.SendCompletionRequest( force_semantic = True )
+ assert_that(
+ ycm.GetCompletionResponse(),
+ has_entries( {
+ 'completions': [
+ { 'word': 'a', 'equal': 1 },
+ { 'word': 'b', 'equal': 1 },
+ { 'word': 'cdef', 'equal': 1 }
+ ],
+ 'completion_start_column': 6
+ } )
+ )
diff --git a/python/ycm/tests/paths_test.py b/python/ycm/tests/paths_test.py
index 31fe67eb4c..9a76351e0e 100644
--- a/python/ycm/tests/paths_test.py
+++ b/python/ycm/tests/paths_test.py
@@ -18,8 +18,8 @@
from ycm.tests.test_utils import MockVimModule
MockVimModule()
-import pytest
from hamcrest import assert_that
+from unittest import TestCase
from ycm.paths import _EndsWithPython
@@ -33,23 +33,26 @@ def EndsWithPython_Bad( path ):
f'Path { path } does end with a Python name.' )
-@pytest.mark.parametrize( 'path', [
- 'python3',
- '/usr/bin/python3.6',
- '/home/user/.pyenv/shims/python3.6',
- r'C:\Python36\python.exe'
- ] )
-def EndsWithPython_Python3Paths_test( path ):
- EndsWithPython_Good( path )
-
-
-@pytest.mark.parametrize( 'path', [
- None,
- '',
- '/opt/local/bin/vim',
- r'C:\Program Files\Vim\vim74\gvim.exe',
- '/usr/bin/python2.7',
- '/home/user/.pyenv/shims/python3.2',
- ] )
-def EndsWithPython_BadPaths_test( path ):
- EndsWithPython_Bad( path )
+class PathTest( TestCase ):
+ def test_EndsWithPython_Python3Paths( self ):
+ for path in [
+ 'python3',
+ '/usr/bin/python3.6',
+ '/home/user/.pyenv/shims/python3.6',
+ r'C:\Python36\python.exe'
+ ]:
+ with self.subTest( path = path ):
+ EndsWithPython_Good( path )
+
+
+ def test_EndsWithPython_BadPaths( self ):
+ for path in [
+ None,
+ '',
+ '/opt/local/bin/vim',
+ r'C:\Program Files\Vim\vim74\gvim.exe',
+ '/usr/bin/python2.7',
+ '/home/user/.pyenv/shims/python3.2',
+ ]:
+ with self.subTest( path = path ):
+ EndsWithPython_Bad( path )
diff --git a/python/ycm/tests/postcomplete_test.py b/python/ycm/tests/postcomplete_test.py
index bc4c64112b..39eb5e5c82 100644
--- a/python/ycm/tests/postcomplete_test.py
+++ b/python/ycm/tests/postcomplete_test.py
@@ -23,6 +23,7 @@
import contextlib
import json
from hamcrest import assert_that, contains_exactly, empty, equal_to, none
+from unittest import TestCase
from unittest.mock import MagicMock, DEFAULT, patch
from ycm import vimsupport
@@ -128,309 +129,319 @@ def _SetUpCompleteDone( completions ):
yield request
-@patch( 'ycm.vimsupport.CurrentFiletypes', return_value = [ 'ycmtest' ] )
-def OnCompleteDone_DefaultFixIt_test( *args ):
- request = CompletionRequest( None )
- request.Done = MagicMock( return_value = True )
- request._OnCompleteDone_Csharp = MagicMock()
- request._OnCompleteDone_FixIt = MagicMock()
- request.OnCompleteDone()
- request._OnCompleteDone_Csharp.assert_not_called()
- request._OnCompleteDone_FixIt.assert_called_once_with()
+class PostcompleteTest( TestCase ):
+ @patch( 'ycm.vimsupport.CurrentFiletypes', return_value = [ 'ycmtest' ] )
+ def test_OnCompleteDone_DefaultFixIt( self, *args ):
+ request = CompletionRequest( None )
+ request.Done = MagicMock( return_value = True )
+ request._OnCompleteDone_Csharp = MagicMock()
+ request._OnCompleteDone_FixIt = MagicMock()
+ request.OnCompleteDone()
+ request._OnCompleteDone_Csharp.assert_not_called()
+ request._OnCompleteDone_FixIt.assert_called_once_with()
-@patch( 'ycm.vimsupport.CurrentFiletypes', return_value = [ 'cs' ] )
-def OnCompleteDone_CsharpFixIt_test( *args ):
- request = CompletionRequest( None )
- request.Done = MagicMock( return_value = True )
- request._OnCompleteDone_Csharp = MagicMock()
- request._OnCompleteDone_FixIt = MagicMock()
- request.OnCompleteDone()
- request._OnCompleteDone_Csharp.assert_called_once_with()
- request._OnCompleteDone_FixIt.assert_not_called()
+ @patch( 'ycm.vimsupport.CurrentFiletypes', return_value = [ 'cs' ] )
+ def test_OnCompleteDone_CsharpFixIt( self, *args ):
+ request = CompletionRequest( None )
+ request.Done = MagicMock( return_value = True )
+ request._OnCompleteDone_Csharp = MagicMock()
+ request._OnCompleteDone_FixIt = MagicMock()
+ request.OnCompleteDone()
+ request._OnCompleteDone_Csharp.assert_called_once_with()
+ request._OnCompleteDone_FixIt.assert_not_called()
-@patch( 'ycm.vimsupport.CurrentFiletypes', return_value = [ 'ycmtest' ] )
-def OnCompleteDone_NoFixItIfNotDone_test( *args ):
- request = CompletionRequest( None )
- request.Done = MagicMock( return_value = False )
- request._OnCompleteDone_Csharp = MagicMock()
- request._OnCompleteDone_FixIt = MagicMock()
- request.OnCompleteDone()
- request._OnCompleteDone_Csharp.assert_not_called()
- request._OnCompleteDone_FixIt.assert_not_called()
+ @patch( 'ycm.vimsupport.CurrentFiletypes', return_value = [ 'ycmtest' ] )
+ def test_OnCompleteDone_NoFixItIfNotDone( self, *args ):
+ request = CompletionRequest( None )
+ request.Done = MagicMock( return_value = False )
+ request._OnCompleteDone_Csharp = MagicMock()
+ request._OnCompleteDone_FixIt = MagicMock()
+ request.OnCompleteDone()
+ request._OnCompleteDone_Csharp.assert_not_called()
+ request._OnCompleteDone_FixIt.assert_not_called()
-@patch( 'ycm.vimsupport.CurrentFiletypes', return_value = [ 'ycmtest' ] )
-def OnCompleteDone_NoFixItForOmnifunc_test( *args ):
- request = OmniCompletionRequest( 'omnifunc', None )
- request.Done = MagicMock( return_value = True )
- request._OnCompleteDone_Csharp = MagicMock()
- request._OnCompleteDone_FixIt = MagicMock()
- request.OnCompleteDone()
- request._OnCompleteDone_Csharp.assert_not_called()
- request._OnCompleteDone_FixIt.assert_not_called()
+ @patch( 'ycm.vimsupport.CurrentFiletypes', return_value = [ 'ycmtest' ] )
+ def test_OnCompleteDone_NoFixItForOmnifunc( self, *args ):
+ request = OmniCompletionRequest( 'omnifunc', None )
+ request.Done = MagicMock( return_value = True )
+ request._OnCompleteDone_Csharp = MagicMock()
+ request._OnCompleteDone_FixIt = MagicMock()
+ request.OnCompleteDone()
+ request._OnCompleteDone_Csharp.assert_not_called()
+ request._OnCompleteDone_FixIt.assert_not_called()
-def FilterToCompletedCompletions_MatchIsReturned_test():
- completions = [ BuildCompletion( insertion_text = 'Test' ) ]
- result = _FilterToMatchingCompletions( CompleteItemIs( 'Test' ), completions )
- assert_that( list( result ), contains_exactly( {} ) )
+ def test_FilterToCompletedCompletions_MatchIsReturned( self ):
+ completions = [ BuildCompletion( insertion_text = 'Test' ) ]
+ result = _FilterToMatchingCompletions( CompleteItemIs( 'Test' ),
+ completions )
+ assert_that( list( result ), contains_exactly( {} ) )
-def FilterToCompletedCompletions_ShortTextDoesntRaise_test():
- completions = [ BuildCompletion( insertion_text = 'AAA' ) ]
- result = _FilterToMatchingCompletions( CompleteItemIs( 'A' ), completions )
- assert_that( list( result ), empty() )
+ def test_FilterToCompletedCompletions_ShortTextDoesntRaise( self ):
+ completions = [ BuildCompletion( insertion_text = 'AAA' ) ]
+ result = _FilterToMatchingCompletions( CompleteItemIs( 'A' ), completions )
+ assert_that( list( result ), empty() )
-def FilterToCompletedCompletions_ExactMatchIsReturned_test():
- completions = [ BuildCompletion( insertion_text = 'Test' ) ]
- result = _FilterToMatchingCompletions( CompleteItemIs( 'Test' ), completions )
- assert_that( list( result ), contains_exactly( {} ) )
+ def test_FilterToCompletedCompletions_ExactMatchIsReturned( self ):
+ completions = [ BuildCompletion( insertion_text = 'Test' ) ]
+ result = _FilterToMatchingCompletions( CompleteItemIs( 'Test' ),
+ completions )
+ assert_that( list( result ), contains_exactly( {} ) )
-def FilterToCompletedCompletions_NonMatchIsntReturned_test():
- completions = [ BuildCompletion( insertion_text = 'A' ) ]
- result = _FilterToMatchingCompletions( CompleteItemIs( ' Quote' ),
- completions )
- assert_that( list( result ), empty() )
+ def test_FilterToCompletedCompletions_NonMatchIsntReturned( self ):
+ completions = [ BuildCompletion( insertion_text = 'A' ) ]
+ result = _FilterToMatchingCompletions( CompleteItemIs( ' Quote' ),
+ completions )
+ assert_that( list( result ), empty() )
-def FilterToCompletedCompletions_Unicode_test():
- completions = [ BuildCompletion( insertion_text = '†es†' ) ]
- result = _FilterToMatchingCompletions( CompleteItemIs( '†es†' ),
- completions )
- assert_that( list( result ), contains_exactly( {} ) )
+ def test_FilterToCompletedCompletions_Unicode( self ):
+ completions = [ BuildCompletion( insertion_text = '†es†' ) ]
+ result = _FilterToMatchingCompletions( CompleteItemIs( '†es†' ),
+ completions )
+ assert_that( list( result ), contains_exactly( {} ) )
-def GetRequiredNamespaceImport_ReturnNoneForNoExtraData_test():
- assert_that( _GetRequiredNamespaceImport( {} ), none() )
+ def test_GetRequiredNamespaceImport_ReturnNoneForNoExtraData( self ):
+ assert_that( _GetRequiredNamespaceImport( {} ), none() )
-def GetRequiredNamespaceImport_ReturnNamespaceFromExtraData_test():
- namespace = 'A_NAMESPACE'
- assert_that( _GetRequiredNamespaceImport(
- BuildCompletionNamespace( namespace )[ 'extra_data' ] ),
- equal_to( namespace ) )
+ def test_GetRequiredNamespaceImport_ReturnNamespaceFromExtraData( self ):
+ namespace = 'A_NAMESPACE'
+ assert_that( _GetRequiredNamespaceImport(
+ BuildCompletionNamespace( namespace )[ 'extra_data' ] ),
+ equal_to( namespace ) )
-@patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs( 'Te' ) )
-def GetExtraDataUserMayHaveCompleted_ReturnEmptyIfPendingMatches_test(
- *args ):
- completions = [ BuildCompletionNamespace( None ) ]
- with _SetupForCsharpCompletionDone( completions ) as request:
- assert_that( request._GetExtraDataUserMayHaveCompleted(), empty() )
+ @patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs( 'Te' ) )
+ def test_GetExtraDataUserMayHaveCompleted_ReturnEmptyIfPendingMatches(
+ *args ):
+ completions = [ BuildCompletionNamespace( None ) ]
+ with _SetupForCsharpCompletionDone( completions ) as request:
+ assert_that( request._GetExtraDataUserMayHaveCompleted(), empty() )
-def GetExtraDataUserMayHaveCompleted_ReturnMatchIfExactMatches_test( *args ):
- info = [ 'NS', 'Test', 'Abbr', 'Menu', 'Info', 'Kind' ]
- completions = [ BuildCompletionNamespace( *info ) ]
- with _SetupForCsharpCompletionDone( completions ) as request:
- with patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs( *info[ 1: ] ) ):
+ def test_GetExtraDataUserMayHaveCompleted_ReturnMatchIfExactMatches(
+ self, *args ):
+ info = [ 'NS', 'Test', 'Abbr', 'Menu', 'Info', 'Kind' ]
+ completions = [ BuildCompletionNamespace( *info ) ]
+ with _SetupForCsharpCompletionDone( completions ) as request:
+ with patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs( *info[ 1: ] ) ):
+ assert_that( request._GetExtraDataUserMayHaveCompleted(),
+ contains_exactly( completions[ 0 ][ 'extra_data' ] ) )
+
+
+ def test_GetExtraDataUserMayHaveCompleted_ReturnMatchIfExactMatchesEvenIfPartial( self ): # noqa
+ info = [ 'NS', 'Test', 'Abbr', 'Menu', 'Info', 'Kind' ]
+ completions = [ BuildCompletionNamespace( *info ),
+ BuildCompletion( insertion_text = 'TestTest' ) ]
+ with _SetupForCsharpCompletionDone( completions ) as request:
+ with patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs( *info[ 1: ] ) ):
+ assert_that( request._GetExtraDataUserMayHaveCompleted(),
+ contains_exactly( completions[ 0 ][ 'extra_data' ] ) )
+
+
+ def test_GetExtraDataUserMayHaveCompleted_DontReturnMatchIfNoExactMatchesAndPartial( self ): # noqa
+ info = [ 'NS', 'Test', 'Abbr', 'Menu', 'Info', 'Kind' ]
+ completions = [ BuildCompletion( insertion_text = info[ 0 ] ),
+ BuildCompletion( insertion_text = 'TestTest' ) ]
+ with _SetupForCsharpCompletionDone( completions ) as request:
+ with patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs( *info[ 1: ] ) ):
+ assert_that( request._GetExtraDataUserMayHaveCompleted(), empty() )
+
+
+ @patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs( 'Test' ) )
+ def test_GetExtraDataUserMayHaveCompleted_ReturnMatchIfMatches( self, *args ):
+ completions = [ BuildCompletionNamespace( None ) ]
+ with _SetupForCsharpCompletionDone( completions ) as request:
assert_that( request._GetExtraDataUserMayHaveCompleted(),
contains_exactly( completions[ 0 ][ 'extra_data' ] ) )
-def GetExtraDataUserMayHaveCompleted_ReturnMatchIfExactMatchesEvenIfPartial_test(): # noqa
- info = [ 'NS', 'Test', 'Abbr', 'Menu', 'Info', 'Kind' ]
- completions = [ BuildCompletionNamespace( *info ),
- BuildCompletion( insertion_text = 'TestTest' ) ]
- with _SetupForCsharpCompletionDone( completions ) as request:
- with patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs( *info[ 1: ] ) ):
- assert_that( request._GetExtraDataUserMayHaveCompleted(),
- contains_exactly( completions[ 0 ][ 'extra_data' ] ) )
+ @patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs(
+ 'Test',
+ user_data=json.dumps( {
+ 'required_namespace_import': 'namespace1' } ) ) )
+ def test_GetExtraDataUserMayHaveCompleted_UseUserData0( self, *args ):
+ # Identical completions but we specify the first one via user_data.
+ completions = [
+ BuildCompletionNamespace( 'namespace1' ),
+ BuildCompletionNamespace( 'namespace2' )
+ ]
+
+ with _SetupForCsharpCompletionDone( completions ) as request:
+ assert_that(
+ request._GetExtraDataUserMayHaveCompleted(),
+ contains_exactly(
+ BuildCompletionNamespace( 'namespace1' )[ 'extra_data' ] ) )
+
+
+ @patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs(
+ 'Test',
+ user_data=json.dumps( {
+ 'required_namespace_import': 'namespace2' } ) ) )
+ def test_GetExtraDataUserMayHaveCompleted_UseUserData1( self, *args ):
+ # Identical completions but we specify the second one via user_data.
+ completions = [
+ BuildCompletionNamespace( 'namespace1' ),
+ BuildCompletionNamespace( 'namespace2' )
+ ]
+
+ with _SetupForCsharpCompletionDone( completions ) as request:
+ assert_that(
+ request._GetExtraDataUserMayHaveCompleted(),
+ contains_exactly(
+ BuildCompletionNamespace( 'namespace2' )[ 'extra_data' ] ) )
+
+
+ @patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs( 'Test', user_data='' ) )
+ def test_GetExtraDataUserMayHaveCompleted_EmptyUserData( self, *args ):
+ # Identical completions but none is selected.
+ completions = [
+ BuildCompletionNamespace( 'namespace1' ),
+ BuildCompletionNamespace( 'namespace2' )
+ ]
+
+ with _SetupForCsharpCompletionDone( completions ) as request:
+ assert_that( request._GetExtraDataUserMayHaveCompleted(), empty() )
-def GetExtraDataUserMayHaveCompleted_DontReturnMatchIfNoExactMatchesAndPartial_test(): # noqa
- info = [ 'NS', 'Test', 'Abbr', 'Menu', 'Info', 'Kind' ]
- completions = [ BuildCompletion( insertion_text = info[ 0 ] ),
- BuildCompletion( insertion_text = 'TestTest' ) ]
- with _SetupForCsharpCompletionDone( completions ) as request:
- with patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs( *info[ 1: ] ) ):
- assert_that( request._GetExtraDataUserMayHaveCompleted(), empty() )
+ @patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs( 'Test' ) )
+ def test_PostCompleteCsharp_EmptyDoesntInsertNamespace( self, *args ):
+ with _SetupForCsharpCompletionDone( [] ) as request:
+ request._OnCompleteDone_Csharp()
+ assert_that( not vimsupport.InsertNamespace.called )
+
+
+ @patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs( 'Test' ) )
+ def test_PostCompleteCsharp_ExistingWithoutNamespaceDoesntInsertNamespace(
+ self, *args ):
+ completions = [ BuildCompletionNamespace( None ) ]
+ with _SetupForCsharpCompletionDone( completions ) as request:
+ request._OnCompleteDone_Csharp()
+ assert_that( not vimsupport.InsertNamespace.called )
+
+
+ @patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs( 'Test' ) )
+ def test_PostCompleteCsharp_ValueDoesInsertNamespace( self, *args ):
+ namespace = 'A_NAMESPACE'
+ completions = [ BuildCompletionNamespace( namespace ) ]
+ with _SetupForCsharpCompletionDone( completions ) as request:
+ request._OnCompleteDone_Csharp()
+ vimsupport.InsertNamespace.assert_called_once_with( namespace )
+
+
+ @patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs( 'Test' ) )
+ @patch( 'ycm.vimsupport.PresentDialog', return_value = 1 )
+ def test_PostCompleteCsharp_InsertSecondNamespaceIfSelected( self, *args ):
+ namespace = 'A_NAMESPACE'
+ namespace2 = 'ANOTHER_NAMESPACE'
+ completions = [
+ BuildCompletionNamespace( namespace ),
+ BuildCompletionNamespace( namespace2 ),
+ ]
+ with _SetupForCsharpCompletionDone( completions ) as request:
+ request._OnCompleteDone_Csharp()
+ vimsupport.InsertNamespace.assert_called_once_with( namespace2 )
+
+
+ @patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs( 'Test' ) )
+ @patch( 'ycm.vimsupport.ReplaceChunks' )
+ def test_PostCompleteFixIt_ApplyFixIt_NoFixIts( self, replace_chunks, *args ):
+ completions = [
+ BuildCompletionFixIt( [] )
+ ]
+ with _SetUpCompleteDone( completions ) as request:
+ request._OnCompleteDone_FixIt()
+ replace_chunks.assert_not_called()
+
+
+ @patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs( 'Test' ) )
+ @patch( 'ycm.vimsupport.ReplaceChunks' )
+ def test_PostCompleteFixIt_ApplyFixIt_EmptyFixIt(
+ self, replace_chunks, *args ):
+ completions = [
+ BuildCompletionFixIt( [ { 'chunks': [] } ] )
+ ]
+ with _SetUpCompleteDone( completions ) as request:
+ request._OnCompleteDone_FixIt()
+ replace_chunks.assert_called_once_with( [], silent = True )
-@patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs( 'Test' ) )
-def GetExtraDataUserMayHaveCompleted_ReturnMatchIfMatches_test( *args ):
- completions = [ BuildCompletionNamespace( None ) ]
- with _SetupForCsharpCompletionDone( completions ) as request:
- assert_that( request._GetExtraDataUserMayHaveCompleted(),
- contains_exactly( completions[ 0 ][ 'extra_data' ] ) )
-
-
-@patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs(
- 'Test',
- user_data=json.dumps( {
- 'required_namespace_import': 'namespace1' } ) ) )
-def GetExtraDataUserMayHaveCompleted_UseUserData0_test( *args ):
- # Identical completions but we specify the first one via user_data.
- completions = [
- BuildCompletionNamespace( 'namespace1' ),
- BuildCompletionNamespace( 'namespace2' )
- ]
-
- with _SetupForCsharpCompletionDone( completions ) as request:
- assert_that( request._GetExtraDataUserMayHaveCompleted(),
- contains_exactly(
- BuildCompletionNamespace( 'namespace1' )[ 'extra_data' ] ) )
-
-
-@patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs(
- 'Test',
- user_data=json.dumps( {
- 'required_namespace_import': 'namespace2' } ) ) )
-def GetExtraDataUserMayHaveCompleted_UseUserData1_test( *args ):
- # Identical completions but we specify the second one via user_data.
- completions = [
- BuildCompletionNamespace( 'namespace1' ),
- BuildCompletionNamespace( 'namespace2' )
- ]
-
- with _SetupForCsharpCompletionDone( completions ) as request:
- assert_that( request._GetExtraDataUserMayHaveCompleted(),
- contains_exactly(
- BuildCompletionNamespace( 'namespace2' )[ 'extra_data' ] ) )
-
-
-@patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs( 'Test', user_data='' ) )
-def GetExtraDataUserMayHaveCompleted_EmptyUserData_test( *args ):
- # Identical completions but none is selected.
- completions = [
- BuildCompletionNamespace( 'namespace1' ),
- BuildCompletionNamespace( 'namespace2' )
- ]
-
- with _SetupForCsharpCompletionDone( completions ) as request:
- assert_that( request._GetExtraDataUserMayHaveCompleted(), empty() )
-
-
-@patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs( 'Test' ) )
-def PostCompleteCsharp_EmptyDoesntInsertNamespace_test( *args ):
- with _SetupForCsharpCompletionDone( [] ) as request:
- request._OnCompleteDone_Csharp()
- assert_that( not vimsupport.InsertNamespace.called )
-
-
-@patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs( 'Test' ) )
-def PostCompleteCsharp_ExistingWithoutNamespaceDoesntInsertNamespace_test(
- *args ):
- completions = [ BuildCompletionNamespace( None ) ]
- with _SetupForCsharpCompletionDone( completions ) as request:
- request._OnCompleteDone_Csharp()
- assert_that( not vimsupport.InsertNamespace.called )
-
-
-@patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs( 'Test' ) )
-def PostCompleteCsharp_ValueDoesInsertNamespace_test( *args ):
- namespace = 'A_NAMESPACE'
- completions = [ BuildCompletionNamespace( namespace ) ]
- with _SetupForCsharpCompletionDone( completions ) as request:
- request._OnCompleteDone_Csharp()
- vimsupport.InsertNamespace.assert_called_once_with( namespace )
-
-
-@patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs( 'Test' ) )
-@patch( 'ycm.vimsupport.PresentDialog', return_value = 1 )
-def PostCompleteCsharp_InsertSecondNamespaceIfSelected_test( *args ):
- namespace = 'A_NAMESPACE'
- namespace2 = 'ANOTHER_NAMESPACE'
- completions = [
- BuildCompletionNamespace( namespace ),
- BuildCompletionNamespace( namespace2 ),
- ]
- with _SetupForCsharpCompletionDone( completions ) as request:
- request._OnCompleteDone_Csharp()
- vimsupport.InsertNamespace.assert_called_once_with( namespace2 )
-
-
-@patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs( 'Test' ) )
-@patch( 'ycm.vimsupport.ReplaceChunks' )
-def PostCompleteFixIt_ApplyFixIt_NoFixIts_test( replace_chunks, *args ):
- completions = [
- BuildCompletionFixIt( [] )
- ]
- with _SetUpCompleteDone( completions ) as request:
- request._OnCompleteDone_FixIt()
- replace_chunks.assert_not_called()
-
-
-@patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs( 'Test' ) )
-@patch( 'ycm.vimsupport.ReplaceChunks' )
-def PostCompleteFixIt_ApplyFixIt_EmptyFixIt_test( replace_chunks, *args ):
- completions = [
- BuildCompletionFixIt( [ { 'chunks': [] } ] )
- ]
- with _SetUpCompleteDone( completions ) as request:
- request._OnCompleteDone_FixIt()
- replace_chunks.assert_called_once_with( [], silent = True )
-
-
-@patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs( 'Test' ) )
-@patch( 'ycm.vimsupport.ReplaceChunks' )
-def PostCompleteFixIt_ApplyFixIt_NoFixIt_test( replace_chunks, *args ):
- completions = [
- BuildCompletion()
- ]
- with _SetUpCompleteDone( completions ) as request:
- request._OnCompleteDone_FixIt()
- replace_chunks.assert_not_called()
-
-
-@patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs( 'Test' ) )
-@patch( 'ycm.vimsupport.ReplaceChunks' )
-def PostCompleteFixIt_ApplyFixIt_PickFirst_test( replace_chunks, *args ):
- completions = [
- BuildCompletionFixIt( [ { 'chunks': 'one' } ] ),
- BuildCompletionFixIt( [ { 'chunks': 'two' } ] ),
- ]
- with _SetUpCompleteDone( completions ) as request:
- request._OnCompleteDone_FixIt()
- replace_chunks.assert_called_once_with( 'one', silent = True )
-
-
-@patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs(
- 'Test',
- user_data=json.dumps( { 'fixits': [ { 'chunks': 'one' } ] } ) ) )
-@patch( 'ycm.vimsupport.ReplaceChunks' )
-def PostCompleteFixIt_ApplyFixIt_PickFirstUserData_test( replace_chunks,
- *args ):
- completions = [
- BuildCompletionFixIt( [ { 'chunks': 'one' } ] ),
- BuildCompletionFixIt( [ { 'chunks': 'two' } ] ),
- ]
- with _SetUpCompleteDone( completions ) as request:
- request._OnCompleteDone_FixIt()
- replace_chunks.assert_called_once_with( 'one', silent = True )
-
-
-@patch( 'ycm.vimsupport.GetVariableValue',
- GetVariableValue_CompleteItemIs(
- 'Test',
- user_data=json.dumps( { 'fixits': [ { 'chunks': 'two' } ] } ) ) )
-@patch( 'ycm.vimsupport.ReplaceChunks' )
-def PostCompleteFixIt_ApplyFixIt_PickSecond_test( replace_chunks, *args ):
- completions = [
- BuildCompletionFixIt( [ { 'chunks': 'one' } ] ),
- BuildCompletionFixIt( [ { 'chunks': 'two' } ] ),
- ]
- with _SetUpCompleteDone( completions ) as request:
- request._OnCompleteDone_FixIt()
- replace_chunks.assert_called_once_with( 'two', silent = True )
+ @patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs( 'Test' ) )
+ @patch( 'ycm.vimsupport.ReplaceChunks' )
+ def test_PostCompleteFixIt_ApplyFixIt_NoFixIt( self, replace_chunks, *args ):
+ completions = [
+ BuildCompletion()
+ ]
+ with _SetUpCompleteDone( completions ) as request:
+ request._OnCompleteDone_FixIt()
+ replace_chunks.assert_not_called()
+
+
+ @patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs( 'Test' ) )
+ @patch( 'ycm.vimsupport.ReplaceChunks' )
+ def test_PostCompleteFixIt_ApplyFixIt_PickFirst(
+ self, replace_chunks, *args ):
+ completions = [
+ BuildCompletionFixIt( [ { 'chunks': 'one' } ] ),
+ BuildCompletionFixIt( [ { 'chunks': 'two' } ] ),
+ ]
+ with _SetUpCompleteDone( completions ) as request:
+ request._OnCompleteDone_FixIt()
+ replace_chunks.assert_called_once_with( 'one', silent = True )
+
+
+ @patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs(
+ 'Test',
+ user_data=json.dumps( { 'fixits': [ { 'chunks': 'one' } ] } ) ) )
+ @patch( 'ycm.vimsupport.ReplaceChunks' )
+ def test_PostCompleteFixIt_ApplyFixIt_PickFirstUserData( self,
+ replace_chunks,
+ *args ):
+ completions = [
+ BuildCompletionFixIt( [ { 'chunks': 'one' } ] ),
+ BuildCompletionFixIt( [ { 'chunks': 'two' } ] ),
+ ]
+ with _SetUpCompleteDone( completions ) as request:
+ request._OnCompleteDone_FixIt()
+ replace_chunks.assert_called_once_with( 'one', silent = True )
+
+
+ @patch( 'ycm.vimsupport.GetVariableValue',
+ GetVariableValue_CompleteItemIs(
+ 'Test',
+ user_data=json.dumps( { 'fixits': [ { 'chunks': 'two' } ] } ) ) )
+ @patch( 'ycm.vimsupport.ReplaceChunks' )
+ def test_PostCompleteFixIt_ApplyFixIt_PickSecond(
+ self, replace_chunks, *args ):
+ completions = [
+ BuildCompletionFixIt( [ { 'chunks': 'one' } ] ),
+ BuildCompletionFixIt( [ { 'chunks': 'two' } ] ),
+ ]
+ with _SetUpCompleteDone( completions ) as request:
+ request._OnCompleteDone_FixIt()
+ replace_chunks.assert_called_once_with( 'two', silent = True )
diff --git a/python/ycm/tests/signature_help_test.py b/python/ycm/tests/signature_help_test.py
index f993376abc..6ff1b4bdee 100644
--- a/python/ycm/tests/signature_help_test.py
+++ b/python/ycm/tests/signature_help_test.py
@@ -17,20 +17,22 @@
from hamcrest import ( assert_that,
empty )
+from unittest import TestCase
from ycm import signature_help as sh
-def MakeSignatureHelpBuffer_Empty_test():
- assert_that( sh._MakeSignatureHelpBuffer( {} ), empty() )
- assert_that( sh._MakeSignatureHelpBuffer( {
- 'activeSignature': 0,
- 'activeParameter': 0,
- 'signatures': []
- } ), empty() )
- assert_that( sh._MakeSignatureHelpBuffer( {
- 'activeSignature': 0,
- 'activeParameter': 0,
- } ), empty() )
- assert_that( sh._MakeSignatureHelpBuffer( {
- 'signatures': []
- } ), empty() )
+class SignatureHelpTest( TestCase ):
+ def test_MakeSignatureHelpBuffer_Empty( self ):
+ assert_that( sh._MakeSignatureHelpBuffer( {} ), empty() )
+ assert_that( sh._MakeSignatureHelpBuffer( {
+ 'activeSignature': 0,
+ 'activeParameter': 0,
+ 'signatures': []
+ } ), empty() )
+ assert_that( sh._MakeSignatureHelpBuffer( {
+ 'activeSignature': 0,
+ 'activeParameter': 0,
+ } ), empty() )
+ assert_that( sh._MakeSignatureHelpBuffer( {
+ 'signatures': []
+ } ), empty() )
diff --git a/python/ycm/tests/syntax_parse_test.py b/python/ycm/tests/syntax_parse_test.py
index a807cd7adc..7cd0e9ea91 100644
--- a/python/ycm/tests/syntax_parse_test.py
+++ b/python/ycm/tests/syntax_parse_test.py
@@ -21,6 +21,7 @@
import os
from hamcrest import assert_that, contains_inanyorder, has_item, has_items
+from unittest import TestCase
from ycm import syntax_parse
from ycmd.utils import ReadFile
@@ -31,191 +32,196 @@ def ContentsOfTestFile( test_file ):
return ReadFile( full_path_to_test_file )
-def KeywordsFromSyntaxListOutput_PythonSyntax_test():
- expected_keywords = (
- 'bytearray', 'IndexError', 'all', 'help', 'vars', 'SyntaxError', 'global',
- 'elif', 'unicode', 'sorted', 'memoryview', 'isinstance', 'except',
- 'nonlocal', 'NameError', 'finally', 'BytesWarning', 'dict', 'IOError',
- 'pass', 'oct', 'bin', 'SystemExit', 'return', 'StandardError', 'format',
- 'TabError', 'break', 'next', 'not', 'UnicodeDecodeError', 'False',
- 'RuntimeWarning', 'list', 'iter', 'try', 'reload', 'Warning', 'round',
- 'dir', 'cmp', 'set', 'bytes', 'UnicodeTranslateError', 'intern',
- 'issubclass', 'yield', 'Ellipsis', 'hash', 'locals', 'BufferError',
- 'slice', 'for', 'FloatingPointError', 'sum', 'VMSError', 'getattr', 'abs',
- 'print', 'import', 'True', 'FutureWarning', 'ImportWarning', 'None',
- 'EOFError', 'len', 'frozenset', 'ord', 'super', 'raise', 'TypeError',
- 'KeyboardInterrupt', 'UserWarning', 'filter', 'range', 'staticmethod',
- 'SystemError', 'or', 'BaseException', 'pow', 'RuntimeError', 'float',
- 'MemoryError', 'StopIteration', 'globals', 'divmod', 'enumerate', 'apply',
- 'LookupError', 'open', 'basestring', 'from', 'UnicodeError', 'zip', 'hex',
- 'long', 'IndentationError', 'int', 'chr', '__import__', 'type',
- 'Exception', 'continue', 'tuple', 'reduce', 'reversed', 'else', 'assert',
- 'UnicodeEncodeError', 'input', 'with', 'hasattr', 'delattr', 'setattr',
- 'raw_input', 'PendingDeprecationWarning', 'compile', 'ArithmeticError',
- 'while', 'del', 'str', 'property', 'def', 'and', 'GeneratorExit',
- 'ImportError', 'xrange', 'is', 'EnvironmentError', 'KeyError', 'coerce',
- 'SyntaxWarning', 'file', 'in', 'unichr', 'ascii', 'any', 'as', 'if',
- 'OSError', 'DeprecationWarning', 'min', 'UnicodeWarning', 'execfile', 'id',
- 'complex', 'bool', 'ValueError', 'NotImplemented', 'map', 'exec', 'buffer',
- 'max', 'class', 'object', 'repr', 'callable', 'ZeroDivisionError', 'eval',
- '__debug__', 'ReferenceError', 'AssertionError', 'classmethod',
- 'UnboundLocalError', 'NotImplementedError', 'lambda', 'AttributeError',
- 'OverflowError', 'WindowsError' )
-
- assert_that( syntax_parse._KeywordsFromSyntaxListOutput(
- ContentsOfTestFile( 'python_syntax' ) ),
- contains_inanyorder( *expected_keywords ) )
-
-
-def KeywordsFromSyntaxListOutput_CppSyntax_test():
- expected_keywords = (
- 'int_fast32_t', 'FILE', 'size_t', 'bitor', 'typedef', 'const', 'struct',
- 'uint8_t', 'fpos_t', 'thread_local', 'unsigned', 'uint_least16_t', 'do',
- 'intptr_t', 'uint_least64_t', 'return', 'auto', 'void', '_Complex',
- 'break', '_Alignof', 'not', 'using', '_Static_assert', '_Thread_local',
- 'public', 'uint_fast16_t', 'this', 'continue', 'char32_t', 'int16_t',
- 'intmax_t', 'static', 'clock_t', 'sizeof', 'int_fast64_t', 'mbstate_t',
- 'try', 'xor', 'uint_fast32_t', 'int_least8_t', 'div_t', 'volatile',
- 'template', 'char16_t', 'new', 'ldiv_t', 'int_least16_t', 'va_list',
- 'uint_least8_t', 'goto', 'noreturn', 'enum', 'static_assert', 'bitand',
- 'compl', 'imaginary', 'jmp_buf', 'throw', 'asm', 'ptrdiff_t', 'uint16_t',
- 'or', 'uint_fast8_t', '_Bool', 'int32_t', 'float', 'private', 'restrict',
- 'wint_t', 'operator', 'not_eq', '_Imaginary', 'alignas', 'union', 'long',
- 'uint_least32_t', 'int_least64_t', 'friend', 'uintptr_t', 'int8_t', 'else',
- 'export', 'int_fast8_t', 'catch', 'true', 'case', 'default', 'double',
- '_Noreturn', 'signed', 'typename', 'while', 'protected', 'wchar_t',
- 'wctrans_t', 'uint64_t', 'delete', 'and', 'register', 'false', 'int',
- 'uintmax_t', 'off_t', 'char', 'int64_t', 'int_fast16_t', 'DIR', '_Atomic',
- 'time_t', 'xor_eq', 'namespace', 'virtual', 'complex', 'bool', 'mutable',
- 'if', 'int_least32_t', 'sig_atomic_t', 'and_eq', 'ssize_t', 'alignof',
- '_Alignas', '_Generic', 'extern', 'class', 'typeid', 'short', 'for',
- 'uint_fast64_t', 'wctype_t', 'explicit', 'or_eq', 'switch', 'uint32_t',
- 'inline' )
-
- assert_that( syntax_parse._KeywordsFromSyntaxListOutput(
- ContentsOfTestFile( 'cpp_syntax' ) ),
- contains_inanyorder( *expected_keywords ) )
-
-
-def KeywordsFromSyntaxListOutput_JavaSyntax_test():
- expected_keywords = (
- 'code', 'text', 'cols', 'datetime', 'disabled', 'shape', 'codetype', 'alt',
- 'compact', 'style', 'valuetype', 'short', 'finally', 'continue', 'extends',
- 'valign', 'bordercolor', 'do', 'return', 'rel', 'rules', 'void',
- 'nohref', 'abbr', 'background', 'scrolling', 'instanceof', 'name',
- 'summary', 'try', 'default', 'noshade', 'coords', 'dir', 'frame', 'usemap',
- 'ismap', 'static', 'hspace', 'vlink', 'for', 'selected', 'rev', 'vspace',
- 'content', 'method', 'version', 'volatile', 'above', 'new', 'charoff',
- 'public', 'alink', 'enum', 'codebase', 'if', 'noresize', 'interface',
- 'checked', 'byte', 'super', 'throw', 'src', 'language', 'package',
- 'standby', 'script', 'longdesc', 'maxlength', 'cellpadding', 'throws',
- 'tabindex', 'color', 'colspan', 'accesskey', 'float', 'while', 'private',
- 'height', 'boolean', 'wrap', 'prompt', 'nowrap', 'size', 'rows', 'span',
- 'clip', 'bgcolor', 'top', 'long', 'start', 'scope', 'scheme', 'type',
- 'final', 'lang', 'visibility', 'else', 'assert', 'transient', 'link',
- 'catch', 'true', 'serializable', 'target', 'lowsrc', 'this', 'double',
- 'align', 'value', 'cite', 'headers', 'below', 'protected', 'declare',
- 'classid', 'defer', 'false', 'synchronized', 'int', 'abstract', 'accept',
- 'hreflang', 'char', 'border', 'id', 'native', 'rowspan', 'charset',
- 'archive', 'strictfp', 'readonly', 'axis', 'cellspacing', 'profile',
- 'multiple', 'object', 'action', 'pagex', 'pagey', 'marginheight', 'data',
- 'class', 'frameborder', 'enctype', 'implements', 'break', 'gutter', 'url',
- 'clear', 'face', 'switch', 'marginwidth', 'width', 'left' )
-
- assert_that( syntax_parse._KeywordsFromSyntaxListOutput(
- ContentsOfTestFile( 'java_syntax' ) ),
- contains_inanyorder( *expected_keywords ) )
-
-
-def KeywordsFromSyntaxListOutput_PhpSyntax_ContainsFunctions_test():
- assert_that( syntax_parse._KeywordsFromSyntaxListOutput(
- ContentsOfTestFile( 'php_syntax' ) ),
- has_items( 'array_change_key_case' ) )
-
-
-def KeywordsFromSyntaxListOutput_PhpSyntax_ContainsPreProc_test():
- assert_that( syntax_parse._KeywordsFromSyntaxListOutput(
- ContentsOfTestFile( 'php_syntax' ) ),
- has_items( 'skip', 'function' ) )
-
-
-def KeywordsFromSyntaxListOutput_Basic_test():
- assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
+class SyntaxTest( TestCase ):
+ def test_KeywordsFromSyntaxListOutput_PythonSyntax( self ):
+ expected_keywords = ( 'bytearray', 'IndexError', 'all', 'help', 'vars',
+ 'SyntaxError', 'global', 'elif', 'unicode', 'sorted', 'memoryview',
+ 'isinstance', 'except', 'nonlocal', 'NameError', 'finally',
+ 'BytesWarning', 'dict', 'IOError', 'pass', 'oct', 'bin', 'SystemExit',
+ 'return', 'StandardError', 'format', 'TabError', 'break', 'next',
+ 'not', 'UnicodeDecodeError', 'False', 'RuntimeWarning', 'list', 'iter',
+ 'try', 'reload', 'Warning', 'round', 'dir', 'cmp', 'set', 'bytes',
+ 'UnicodeTranslateError', 'intern', 'issubclass', 'yield', 'Ellipsis',
+ 'hash', 'locals', 'BufferError', 'slice', 'for', 'FloatingPointError',
+ 'sum', 'VMSError', 'getattr', 'abs', 'print', 'import', 'True',
+ 'FutureWarning', 'ImportWarning', 'None', 'EOFError', 'len',
+ 'frozenset', 'ord', 'super', 'raise', 'TypeError', 'KeyboardInterrupt',
+ 'UserWarning', 'filter', 'range', 'staticmethod', 'SystemError', 'or',
+ 'BaseException', 'pow', 'RuntimeError', 'float', 'MemoryError',
+ 'StopIteration', 'globals', 'divmod', 'enumerate', 'apply',
+ 'LookupError', 'open', 'basestring', 'from', 'UnicodeError', 'zip',
+ 'hex', 'long', 'IndentationError', 'int', 'chr', '__import__', 'type',
+ 'Exception', 'continue', 'tuple', 'reduce', 'reversed', 'else',
+ 'assert', 'UnicodeEncodeError', 'input', 'with', 'hasattr', 'delattr',
+ 'setattr', 'raw_input', 'PendingDeprecationWarning', 'compile',
+ 'ArithmeticError', 'while', 'del', 'str', 'property', 'def', 'and',
+ 'GeneratorExit', 'ImportError', 'xrange', 'is', 'EnvironmentError',
+ 'KeyError', 'coerce', 'SyntaxWarning', 'file', 'in', 'unichr', 'ascii',
+ 'any', 'as', 'if', 'OSError', 'DeprecationWarning', 'min',
+ 'UnicodeWarning', 'execfile', 'id', 'complex', 'bool', 'ValueError',
+ 'NotImplemented', 'map', 'exec', 'buffer', 'max', 'class', 'object',
+ 'repr', 'callable', 'ZeroDivisionError', 'eval', '__debug__',
+ 'ReferenceError', 'AssertionError', 'classmethod', 'UnboundLocalError',
+ 'NotImplementedError', 'lambda', 'AttributeError', 'OverflowError',
+ 'WindowsError' )
+
+ assert_that( syntax_parse._KeywordsFromSyntaxListOutput(
+ ContentsOfTestFile( 'python_syntax' ) ),
+ contains_inanyorder( *expected_keywords ) )
+
+
+ def test_KeywordsFromSyntaxListOutput_CppSyntax( self ):
+ expected_keywords = (
+ 'int_fast32_t', 'FILE', 'size_t', 'bitor', 'typedef', 'const', 'struct',
+ 'uint8_t', 'fpos_t', 'thread_local', 'unsigned', 'uint_least16_t', 'do',
+ 'intptr_t', 'uint_least64_t', 'return', 'auto', 'void', '_Complex',
+ 'break', '_Alignof', 'not', 'using', '_Static_assert', '_Thread_local',
+ 'public', 'uint_fast16_t', 'this', 'continue', 'char32_t', 'int16_t',
+ 'intmax_t', 'static', 'clock_t', 'sizeof', 'int_fast64_t', 'mbstate_t',
+ 'try', 'xor', 'uint_fast32_t', 'int_least8_t', 'div_t', 'volatile',
+ 'template', 'char16_t', 'new', 'ldiv_t', 'int_least16_t', 'va_list',
+ 'uint_least8_t', 'goto', 'noreturn', 'enum', 'static_assert', 'bitand',
+ 'compl', 'imaginary', 'jmp_buf', 'throw', 'asm', 'ptrdiff_t', 'uint16_t',
+ 'or', 'uint_fast8_t', '_Bool', 'int32_t', 'float', 'private', 'restrict',
+ 'wint_t', 'operator', 'not_eq', '_Imaginary', 'alignas', 'union', 'long',
+ 'uint_least32_t', 'int_least64_t', 'friend', 'uintptr_t', 'int8_t',
+ 'else', 'export', 'int_fast8_t', 'catch', 'true', 'case', 'default',
+ 'double', '_Noreturn', 'signed', 'typename', 'while', 'protected',
+ 'wchar_t', 'wctrans_t', 'uint64_t', 'delete', 'and', 'register', 'false',
+ 'int', 'uintmax_t', 'off_t', 'char', 'int64_t', 'int_fast16_t', 'DIR',
+ '_Atomic', 'time_t', 'xor_eq', 'namespace', 'virtual', 'complex', 'bool',
+ 'mutable', 'if', 'int_least32_t', 'sig_atomic_t', 'and_eq', 'ssize_t',
+ 'alignof', '_Alignas', '_Generic', 'extern', 'class', 'typeid', 'short',
+ 'for', 'uint_fast64_t', 'wctype_t', 'explicit', 'or_eq', 'switch',
+ 'uint32_t', 'inline' )
+
+ assert_that( syntax_parse._KeywordsFromSyntaxListOutput(
+ ContentsOfTestFile( 'cpp_syntax' ) ),
+ contains_inanyorder( *expected_keywords ) )
+
+
+ def test_KeywordsFromSyntaxListOutput_JavaSyntax( self ):
+ expected_keywords = (
+ 'code', 'text', 'cols', 'datetime', 'disabled', 'shape', 'codetype',
+ 'alt', 'compact', 'style', 'valuetype', 'short', 'finally', 'continue',
+ 'extends', 'valign', 'bordercolor', 'do', 'return', 'rel', 'rules',
+ 'void', 'nohref', 'abbr', 'background', 'scrolling', 'instanceof',
+ 'name', 'summary', 'try', 'default', 'noshade', 'coords', 'dir', 'frame',
+ 'usemap', 'ismap', 'static', 'hspace', 'vlink', 'for', 'selected', 'rev',
+ 'vspace', 'content', 'method', 'version', 'volatile', 'above', 'new',
+ 'charoff', 'public', 'alink', 'enum', 'codebase', 'if', 'noresize',
+ 'interface', 'checked', 'byte', 'super', 'throw', 'src', 'language',
+ 'package', 'standby', 'script', 'longdesc', 'maxlength', 'cellpadding',
+ 'throws', 'tabindex', 'color', 'colspan', 'accesskey', 'float', 'while',
+ 'private', 'height', 'boolean', 'wrap', 'prompt', 'nowrap', 'size',
+ 'rows', 'span', 'clip', 'bgcolor', 'top', 'long', 'start', 'scope',
+ 'scheme', 'type', 'final', 'lang', 'visibility', 'else', 'assert',
+ 'transient', 'link', 'catch', 'true', 'serializable', 'target', 'lowsrc',
+ 'this', 'double', 'align', 'value', 'cite', 'headers', 'below',
+ 'protected', 'declare', 'classid', 'defer', 'false', 'synchronized',
+ 'int', 'abstract', 'accept', 'hreflang', 'char', 'border', 'id',
+ 'native', 'rowspan', 'charset', 'archive', 'strictfp', 'readonly',
+ 'axis', 'cellspacing', 'profile', 'multiple', 'object', 'action',
+ 'pagex', 'pagey', 'marginheight', 'data', 'class', 'frameborder',
+ 'enctype', 'implements', 'break', 'gutter', 'url', 'clear', 'face',
+ 'switch', 'marginwidth', 'width', 'left' )
+
+ assert_that( syntax_parse._KeywordsFromSyntaxListOutput(
+ ContentsOfTestFile( 'java_syntax' ) ),
+ contains_inanyorder( *expected_keywords ) )
+
+
+ def test_KeywordsFromSyntaxListOutput_PhpSyntax_ContainsFunctions( self ):
+ assert_that( syntax_parse._KeywordsFromSyntaxListOutput(
+ ContentsOfTestFile( 'php_syntax' ) ),
+ has_items( 'array_change_key_case' ) )
+
+
+ def test_KeywordsFromSyntaxListOutput_PhpSyntax_ContainsPreProc( self ):
+ assert_that( syntax_parse._KeywordsFromSyntaxListOutput(
+ ContentsOfTestFile( 'php_syntax' ) ),
+ has_items( 'skip', 'function' ) )
+
+
+ def test_KeywordsFromSyntaxListOutput_Basic( self ):
+ assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
foogroup xxx foo bar
zoo goo
links to Statement""" ),
- contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
+ contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
-def KeywordsFromSyntaxListOutput_Function_test():
- assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
+ def test_KeywordsFromSyntaxListOutput_Function( self ):
+ assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
foogroup xxx foo bar
zoo goo
links to Function""" ),
- contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
+ contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
-def KeywordsFromSyntaxListOutput_ContainedArgAllowed_test():
- assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
+ def test_KeywordsFromSyntaxListOutput_ContainedArgAllowed( self ):
+ assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
phpFunctions xxx contained gzclose yaz_syntax html_entity_decode fbsql_read_blob png2wbmp mssql_init cpdf_set_title gztell fbsql_insert_id empty cpdf_restore mysql_field_type closelog swftext ldap_search curl_errno gmp_div_r mssql_data_seek getmyinode printer_draw_pie mcve_initconn ncurses_getmaxyx defined
contained replace_child has_attributes specified insertdocument assign node_name hwstat addshape get_attribute_node html_dump_mem userlist
links to Function""" ), # noqa
- has_items( 'gzclose', 'userlist', 'ldap_search' ) )
+ has_items( 'gzclose', 'userlist', 'ldap_search' ) )
-def KeywordsFromSyntaxListOutput_JunkIgnored_test():
- assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
+ def test_KeywordsFromSyntaxListOutput_JunkIgnored( self ):
+ assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
--- Syntax items ---
foogroup xxx foo bar
zoo goo
links to Statement
Spell cluster=NONE
NoSpell cluster=NONE""" ),
- contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
+ contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
-def KeywordsFromSyntaxListOutput_MultipleStatementGroups_test():
- assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
+ def test_KeywordsFromSyntaxListOutput_MultipleStatementGroups( self ):
+ assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
foogroup xxx foo bar
links to Statement
bargroup xxx zoo goo
links to Statement""" ),
- contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
+ contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
-def KeywordsFromSyntaxListOutput_StatementAndTypeGroups_test():
- assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
+ def test_KeywordsFromSyntaxListOutput_StatementAndTypeGroups( self ):
+ assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
foogroup xxx foo bar
links to Statement
bargroup xxx zoo goo
links to Type""" ),
- contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
+ contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
-def KeywordsFromSyntaxListOutput_StatementHierarchy_test():
- assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
+ def test_KeywordsFromSyntaxListOutput_StatementHierarchy( self ):
+ assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
baa xxx foo bar
links to Foo
Foo xxx zoo goo
links to Bar
Bar xxx qux moo
links to Statement""" ),
- contains_inanyorder( 'foo', 'bar', 'zoo', 'goo', 'qux', 'moo' ) )
+ contains_inanyorder( 'foo', 'bar', 'zoo',
+ 'goo', 'qux', 'moo' ) )
-def KeywordsFromSyntaxListOutput_TypeHierarchy_test():
- assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
+ def test_KeywordsFromSyntaxListOutput_TypeHierarchy( self ):
+ assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
baa xxx foo bar
links to Foo
Foo xxx zoo goo
links to Bar
Bar xxx qux moo
links to Type""" ),
- contains_inanyorder( 'foo', 'bar', 'zoo', 'goo', 'qux', 'moo' ) )
+ contains_inanyorder( 'foo', 'bar', 'zoo',
+ 'goo', 'qux', 'moo' ) )
-def KeywordsFromSyntaxListOutput_StatementAndTypeHierarchy_test():
- assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
+ def test_KeywordsFromSyntaxListOutput_StatementAndTypeHierarchy( self ):
+ assert_that( syntax_parse._KeywordsFromSyntaxListOutput( """
tBaa xxx foo bar
links to tFoo
tFoo xxx zoo goo
@@ -228,97 +234,100 @@ def KeywordsFromSyntaxListOutput_StatementAndTypeHierarchy_test():
links to sBar
sBar xxx qux nc
links to Statement""" ),
- contains_inanyorder( 'foo', 'bar', 'zoo', 'goo', 'qux', 'moo',
- 'na', 'nb', 'nc' ) )
+ contains_inanyorder( 'foo', 'bar', 'zoo', 'goo', 'qux', 'moo',
+ 'na', 'nb', 'nc' ) )
-def SyntaxGroupsFromOutput_Basic_test():
- assert_that( syntax_parse._SyntaxGroupsFromOutput( """
+ def test_SyntaxGroupsFromOutput_Basic( self ):
+ assert_that( syntax_parse._SyntaxGroupsFromOutput( """
foogroup xxx foo bar
zoo goo
links to Statement""" ),
- has_item( 'foogroup' ) )
-
-
-def ExtractKeywordsFromGroup_Basic_test():
- assert_that( syntax_parse._ExtractKeywordsFromGroup(
- syntax_parse.SyntaxGroup( '', [
- 'foo bar',
- 'zoo goo',
- ] ) ),
- contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
-
-
-def ExtractKeywordsFromGroup_Commas_test():
- assert_that( syntax_parse._ExtractKeywordsFromGroup(
- syntax_parse.SyntaxGroup( '', [
- 'foo, bar,',
- 'zoo goo',
- ] ) ),
- contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
-
-
-def ExtractKeywordsFromGroup_WithLinksTo_test():
- assert_that( syntax_parse._ExtractKeywordsFromGroup(
- syntax_parse.SyntaxGroup( '', [
- 'foo bar',
- 'zoo goo',
- 'links to Statement'
- ] ) ),
- contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
-
-
-def ExtractKeywordsFromGroup_KeywordStarts_test():
- assert_that( syntax_parse._ExtractKeywordsFromGroup(
- syntax_parse.SyntaxGroup( '', [
- 'foo bar',
- 'contained boo baa',
- 'zoo goo',
- ] ) ),
- contains_inanyorder( 'foo', 'bar', 'boo', 'baa', 'zoo', 'goo' ) )
-
-
-def ExtractKeywordsFromGroup_KeywordMiddle_test():
- assert_that( syntax_parse._ExtractKeywordsFromGroup(
- syntax_parse.SyntaxGroup( '', [
- 'foo contained bar',
- 'zoo goo'
- ] ) ),
- contains_inanyorder( 'foo', 'contained', 'bar', 'zoo', 'goo' ) )
-
-
-def ExtractKeywordsFromGroup_KeywordAssign_test():
- assert_that( syntax_parse._ExtractKeywordsFromGroup(
- syntax_parse.SyntaxGroup( '', [
- 'nextgroup=zoo skipwhite foo bar',
- 'zoo goo',
- ] ) ),
- contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
-
-
-def ExtractKeywordsFromGroup_KeywordAssignAndMiddle_test():
- assert_that( syntax_parse._ExtractKeywordsFromGroup(
- syntax_parse.SyntaxGroup( '', [
- 'nextgroup=zoo foo skipnl bar',
- 'zoo goo',
- ] ) ),
- contains_inanyorder( 'foo', 'skipnl', 'bar', 'zoo', 'goo' ) )
-
-
-def ExtractKeywordsFromGroup_KeywordWithoutNextgroup_test():
- assert_that( syntax_parse._ExtractKeywordsFromGroup(
- syntax_parse.SyntaxGroup( '', [
- 'skipempty foo bar',
- 'zoo goo',
- ] ) ),
- contains_inanyorder( 'skipempty', 'foo', 'bar', 'zoo', 'goo' ) )
-
-
-def ExtractKeywordsFromGroup_ContainedSyntaxArgAllowed_test():
- assert_that( syntax_parse._ExtractKeywordsFromGroup(
- syntax_parse.SyntaxGroup( '', [
- 'contained foo zoq',
- 'contained bar goo',
- 'far'
- ] ) ),
- contains_inanyorder( 'foo', 'zoq', 'bar', 'goo', 'far' ) )
+ has_item( 'foogroup' ) )
+
+
+ def test_ExtractKeywordsFromGroup_Basic( self ):
+ assert_that( syntax_parse._ExtractKeywordsFromGroup(
+ syntax_parse.SyntaxGroup( '', [
+ 'foo bar',
+ 'zoo goo',
+ ] ) ),
+ contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
+
+
+ def test_ExtractKeywordsFromGroup_Commas( self ):
+ assert_that( syntax_parse._ExtractKeywordsFromGroup(
+ syntax_parse.SyntaxGroup( '', [
+ 'foo, bar,',
+ 'zoo goo',
+ ] ) ),
+ contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
+
+
+ def test_ExtractKeywordsFromGroup_WithLinksTo( self ):
+ assert_that( syntax_parse._ExtractKeywordsFromGroup(
+ syntax_parse.SyntaxGroup( '', [
+ 'foo bar',
+ 'zoo goo',
+ 'links to Statement'
+ ] ) ),
+ contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
+
+
+ def test_ExtractKeywordsFromGroup_KeywordStarts( self ):
+ assert_that( syntax_parse._ExtractKeywordsFromGroup(
+ syntax_parse.SyntaxGroup( '', [
+ 'foo bar',
+ 'contained boo baa',
+ 'zoo goo',
+ ] ) ),
+ contains_inanyorder( 'foo', 'bar', 'boo',
+ 'baa', 'zoo', 'goo' ) )
+
+
+ def test_ExtractKeywordsFromGroup_KeywordMiddle( self ):
+ assert_that( syntax_parse._ExtractKeywordsFromGroup(
+ syntax_parse.SyntaxGroup( '', [
+ 'foo contained bar',
+ 'zoo goo'
+ ] ) ),
+ contains_inanyorder( 'foo', 'contained',
+ 'bar', 'zoo', 'goo' ) )
+
+
+ def test_ExtractKeywordsFromGroup_KeywordAssign( self ):
+ assert_that( syntax_parse._ExtractKeywordsFromGroup(
+ syntax_parse.SyntaxGroup( '', [
+ 'nextgroup=zoo skipwhite foo bar',
+ 'zoo goo',
+ ] ) ),
+ contains_inanyorder( 'foo', 'bar', 'zoo', 'goo' ) )
+
+
+ def test_ExtractKeywordsFromGroup_KeywordAssignAndMiddle( self ):
+ assert_that( syntax_parse._ExtractKeywordsFromGroup(
+ syntax_parse.SyntaxGroup( '', [
+ 'nextgroup=zoo foo skipnl bar',
+ 'zoo goo',
+ ] ) ),
+ contains_inanyorder( 'foo', 'skipnl', 'bar', 'zoo', 'goo' ) )
+
+
+ def test_ExtractKeywordsFromGroup_KeywordWithoutNextgroup( self ):
+ assert_that( syntax_parse._ExtractKeywordsFromGroup(
+ syntax_parse.SyntaxGroup( '', [
+ 'skipempty foo bar',
+ 'zoo goo',
+ ] ) ),
+ contains_inanyorder( 'skipempty', 'foo',
+ 'bar', 'zoo', 'goo' ) )
+
+
+ def test_ExtractKeywordsFromGroup_ContainedSyntaxArgAllowed( self ):
+ assert_that( syntax_parse._ExtractKeywordsFromGroup(
+ syntax_parse.SyntaxGroup( '', [
+ 'contained foo zoq',
+ 'contained bar goo',
+ 'far'
+ ] ) ),
+ contains_inanyorder( 'foo', 'zoq', 'bar', 'goo', 'far' ) )
diff --git a/python/ycm/tests/test_utils.py b/python/ycm/tests/test_utils.py
index d6cdd7d79c..86b75c8834 100644
--- a/python/ycm/tests/test_utils.py
+++ b/python/ycm/tests/test_utils.py
@@ -17,11 +17,11 @@
from collections import defaultdict, namedtuple
from unittest.mock import DEFAULT, MagicMock, patch
+from unittest import skip
from hamcrest import assert_that, equal_to
import contextlib
import functools
import json
-import pytest
import os
import re
import sys
@@ -712,7 +712,7 @@ def Wrapper( *args, **kwargs ):
raise test_exception
# Failed for the right reason
- pytest.skip( reason )
+ skip( reason )
else:
raise AssertionError( f'Test was expected to fail: { reason }' )
return Wrapper
diff --git a/python/ycm/tests/vimsupport_test.py b/python/ycm/tests/vimsupport_test.py
index 1e25ae03d3..1b2d890b58 100644
--- a/python/ycm/tests/vimsupport_test.py
+++ b/python/ycm/tests/vimsupport_test.py
@@ -23,1935 +23,1885 @@
from ycm import vimsupport
from hamcrest import ( assert_that, calling, contains_exactly, empty, equal_to,
has_entry, raises )
+from unittest import TestCase
from unittest.mock import MagicMock, call, patch
from ycmd.utils import ToBytes
import os
import json
-@patch( 'vim.eval', new_callable = ExtendedMock )
-def SetLocationListsForBuffer_Current_test( vim_eval ):
- diagnostics = [ {
- 'bufnr': 3,
- 'filename': 'some_filename',
- 'lnum': 5,
- 'col': 22,
- 'type': 'E',
- 'valid': 1
- } ]
- current_buffer = VimBuffer( '/test', number = 3 )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- vimsupport.SetLocationListsForBuffer( 3, diagnostics )
-
- vim_eval.assert_has_exact_calls( [
- call( f'setloclist( 1, { json.dumps( diagnostics ) } )' )
- ] )
-
-
-@patch( 'vim.eval', new_callable = ExtendedMock )
-def SetLocationListsForBuffer_NotCurrent_test( vim_eval ):
- diagnostics = [ {
- 'bufnr': 3,
- 'filename': 'some_filename',
- 'lnum': 5,
- 'col': 22,
- 'type': 'E',
- 'valid': 1
- } ]
- current_buffer = VimBuffer( '/test', number = 3 )
- other_buffer = VimBuffer( '/notcurrent', number = 1 )
- with MockVimBuffers( [ current_buffer, other_buffer ], [ current_buffer ] ):
- vimsupport.SetLocationListsForBuffer( 1, diagnostics )
-
- vim_eval.assert_not_called()
-
-
-@patch( 'vim.eval', new_callable = ExtendedMock, side_effect = [ -1, 1 ] )
-def SetLocationListsForBuffer_NotVisible_test( vim_eval ):
- diagnostics = [ {
- 'bufnr': 3,
- 'filename': 'some_filename',
- 'lnum': 5,
- 'col': 22,
- 'type': 'E',
- 'valid': 1
- } ]
- current_buffer = VimBuffer( '/test', number = 3 )
- other_buffer = VimBuffer( '/notcurrent', number = 1 )
- with MockVimBuffers( [ current_buffer, other_buffer ], [ current_buffer ] ):
- vimsupport.SetLocationListsForBuffer( 1, diagnostics )
-
- vim_eval.assert_not_called()
-
-
-@patch( 'vim.eval', new_callable = ExtendedMock, side_effect = [ -1, 1 ] )
-def SetLocationListsForBuffer_MultipleWindows_test( vim_eval ):
- diagnostics = [ {
- 'bufnr': 3,
- 'filename': 'some_filename',
- 'lnum': 5,
- 'col': 22,
- 'type': 'E',
- 'valid': 1
- } ]
- current_buffer = VimBuffer( '/test', number = 3 )
- other_buffer = VimBuffer( '/notcurrent', number = 1 )
- with MockVimBuffers( [ current_buffer, other_buffer ],
- [ current_buffer, other_buffer ] ):
- vimsupport.SetLocationListsForBuffer( 1, diagnostics )
-
- vim_eval.assert_has_exact_calls( [
- call( f'setloclist( 2, { json.dumps( diagnostics ) } )' )
- ] )
-
-
-@patch( 'vim.eval', new_callable = ExtendedMock )
-def SetLocationList_test( vim_eval ):
- diagnostics = [ {
- 'bufnr': 3,
- 'filename': 'some_filename',
- 'lnum': 5,
- 'col': 22,
- 'type': 'E',
- 'valid': 1
- } ]
- current_buffer = VimBuffer( '/test', number = 3 )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ):
- vimsupport.SetLocationList( diagnostics )
-
- vim_eval.assert_has_calls( [
- call( f'setloclist( 0, { json.dumps( diagnostics ) } )' )
- ] )
-
-
-@patch( 'vim.eval', new_callable = ExtendedMock )
-def SetLocationList_NotCurrent_test( vim_eval ):
- diagnostics = [ {
- 'bufnr': 3,
- 'filename': 'some_filename',
- 'lnum': 5,
- 'col': 22,
- 'type': 'E',
- 'valid': 1
- } ]
- current_buffer = VimBuffer( '/test', number = 3 )
- other_buffer = VimBuffer( '/notcurrent', number = 1 )
- with MockVimBuffers( [ current_buffer, other_buffer ],
- [ current_buffer, other_buffer ],
- ( 1, 1 ) ):
- vimsupport.SetLocationList( diagnostics )
-
- # This version does not check the current buffer and just sets the current win
- vim_eval.assert_has_exact_calls( [
- call( f'setloclist( 0, { json.dumps( diagnostics ) } )' )
- ] )
-
-
-@patch( 'ycm.vimsupport.VariableExists', return_value = True )
-@patch( 'ycm.vimsupport.SetFittingHeightForCurrentWindow' )
-@patch( 'vim.command', new_callable = ExtendedMock )
-def OpenLocationList_test( vim_command, fitting_height, variable_exists ):
- vimsupport.OpenLocationList( focus = False, autoclose = True )
- vim_command.assert_has_exact_calls( [
- call( 'lopen' ),
- call( 'augroup ycmlocation' ),
- call( 'autocmd! * ' ),
- call( 'autocmd WinLeave '
- 'if bufnr( "%" ) == expand( "" ) | q | endif '
- '| autocmd! ycmlocation' ),
- call( 'augroup END' ),
- call( 'doautocmd User YcmLocationOpened' ),
- call( 'silent! wincmd p' )
- ] )
- fitting_height.assert_called_once_with()
- variable_exists.assert_called_once_with( '#User#YcmLocationOpened' )
-
-
-@patch( 'vim.command' )
-def SetFittingHeightForCurrentWindow_LineWrapOn_test( vim_command, *args ):
- # Create a two lines buffer whose first line is longer than the window width.
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'a' * 140, 'b' * 80 ] )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
- vim.current.window.width = 120
- vim.current.window.options[ 'wrap' ] = True
- vimsupport.SetFittingHeightForCurrentWindow()
- vim_command.assert_called_once_with( '3wincmd _' )
-
-
-@patch( 'vim.command' )
-def SetFittingHeightForCurrentWindow_NoResize_test( vim_command, *args ):
- # Create a two lines buffer whose first line is longer than the window width.
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'a' * 140, 'b' * 80 ],
- vars = { 'ycm_no_resize': 1 } )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
- vim.current.window.width = 120
- vim.current.window.options[ 'wrap' ] = True
- vimsupport.SetFittingHeightForCurrentWindow()
- vim_command.assert_not_called()
-
-
-@patch( 'vim.command' )
-def SetFittingHeightForCurrentWindow_LineWrapOff_test( vim_command, *args ):
- # Create a two lines buffer whose first line is longer than the window width.
- current_buffer = VimBuffer( 'buffer',
- contents = [ 'a' * 140, 'b' * 80 ] )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
- vim.current.window.width = 120
- vim.current.window.options[ 'wrap' ] = False
- vimsupport.SetFittingHeightForCurrentWindow()
- vim_command.assert_called_once_with( '2wincmd _' )
-
-
def AssertBuffersAreEqualAsBytes( result_buffer, expected_buffer ):
assert_that( len( result_buffer ), equal_to( len( expected_buffer ) ) )
for result_line, expected_line in zip( result_buffer, expected_buffer ):
assert_that( ToBytes( result_line ), equal_to( ToBytes( expected_line ) ) )
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleLine_Repl_1_test():
- # Replace with longer range
- result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
- start, end = _BuildLocations( 1, 11, 1, 17 )
- vimsupport.ReplaceChunk( start, end, 'pie', result_buffer )
+def _BuildChunk( start_line,
+ start_column,
+ end_line,
+ end_column,
+ replacement_text, filepath='test_file_name' ):
+ return {
+ 'range': {
+ 'start': {
+ 'filepath': filepath,
+ 'line_num': start_line,
+ 'column_num': start_column,
+ },
+ 'end': {
+ 'filepath': filepath,
+ 'line_num': end_line,
+ 'column_num': end_column,
+ },
+ },
+ 'replacement_text': replacement_text
+ }
- AssertBuffersAreEqualAsBytes( [ 'This is a pie' ], result_buffer )
- # and replace again
- start, end = _BuildLocations( 1, 10, 1, 11 )
- vimsupport.ReplaceChunk( start, end, ' piece of ', result_buffer )
+def _BuildLocations( start_line, start_column, end_line, end_column ):
+ return {
+ 'line_num' : start_line,
+ 'column_num': start_column,
+ }, {
+ 'line_num' : end_line,
+ 'column_num': end_column,
+ }
- AssertBuffersAreEqualAsBytes( [ 'This is a piece of pie' ], result_buffer )
- # and once more, for luck
- start, end = _BuildLocations( 1, 1, 1, 5 )
- vimsupport.ReplaceChunk( start, end, 'How long', result_buffer )
+class VimsupportTest( TestCase ):
+ @patch( 'vim.eval', new_callable = ExtendedMock )
+ def test_SetLocationListsForBuffer_Current( self, vim_eval ):
+ diagnostics = [ {
+ 'bufnr': 3,
+ 'filename': 'some_filename',
+ 'lnum': 5,
+ 'col': 22,
+ 'type': 'E',
+ 'valid': 1
+ } ]
+ current_buffer = VimBuffer( '/test', number = 3 )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ vimsupport.SetLocationListsForBuffer( 3, diagnostics )
+
+ vim_eval.assert_has_exact_calls( [
+ call( f'setloclist( 1, { json.dumps( diagnostics ) } )' )
+ ] )
- AssertBuffersAreEqualAsBytes( [ 'How long is a piece of pie' ],
- result_buffer )
+ @patch( 'vim.eval', new_callable = ExtendedMock )
+ def test_SetLocationListsForBuffer_NotCurrent( self, vim_eval ):
+ diagnostics = [ {
+ 'bufnr': 3,
+ 'filename': 'some_filename',
+ 'lnum': 5,
+ 'col': 22,
+ 'type': 'E',
+ 'valid': 1
+ } ]
+ current_buffer = VimBuffer( '/test', number = 3 )
+ other_buffer = VimBuffer( '/notcurrent', number = 1 )
+ with MockVimBuffers( [ current_buffer, other_buffer ], [ current_buffer ] ):
+ vimsupport.SetLocationListsForBuffer( 1, diagnostics )
+
+ vim_eval.assert_not_called()
+
+
+ @patch( 'vim.eval', new_callable = ExtendedMock, side_effect = [ -1, 1 ] )
+ def test_SetLocationListsForBuffer_NotVisible( self, vim_eval ):
+ diagnostics = [ {
+ 'bufnr': 3,
+ 'filename': 'some_filename',
+ 'lnum': 5,
+ 'col': 22,
+ 'type': 'E',
+ 'valid': 1
+ } ]
+ current_buffer = VimBuffer( '/test', number = 3 )
+ other_buffer = VimBuffer( '/notcurrent', number = 1 )
+ with MockVimBuffers( [ current_buffer, other_buffer ], [ current_buffer ] ):
+ vimsupport.SetLocationListsForBuffer( 1, diagnostics )
+
+ vim_eval.assert_not_called()
+
+
+ @patch( 'vim.eval', new_callable = ExtendedMock, side_effect = [ -1, 1 ] )
+ def test_SetLocationListsForBuffer_MultipleWindows( self, vim_eval ):
+ diagnostics = [ {
+ 'bufnr': 3,
+ 'filename': 'some_filename',
+ 'lnum': 5,
+ 'col': 22,
+ 'type': 'E',
+ 'valid': 1
+ } ]
+ current_buffer = VimBuffer( '/test', number = 3 )
+ other_buffer = VimBuffer( '/notcurrent', number = 1 )
+ with MockVimBuffers( [ current_buffer, other_buffer ],
+ [ current_buffer, other_buffer ] ):
+ vimsupport.SetLocationListsForBuffer( 1, diagnostics )
+
+ vim_eval.assert_has_exact_calls( [
+ call( f'setloclist( 2, { json.dumps( diagnostics ) } )' )
+ ] )
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleLine_Repl_2_test():
- # Replace with shorter range
- result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
- start, end = _BuildLocations( 1, 11, 1, 17 )
- vimsupport.ReplaceChunk( start, end, 'test', result_buffer )
- AssertBuffersAreEqualAsBytes( [ 'This is a test' ], result_buffer )
+ @patch( 'vim.eval', new_callable = ExtendedMock )
+ def test_SetLocationList( self, vim_eval ):
+ diagnostics = [ {
+ 'bufnr': 3,
+ 'filename': 'some_filename',
+ 'lnum': 5,
+ 'col': 22,
+ 'type': 'E',
+ 'valid': 1
+ } ]
+ current_buffer = VimBuffer( '/test', number = 3 )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ):
+ vimsupport.SetLocationList( diagnostics )
+
+ vim_eval.assert_has_calls( [
+ call( f'setloclist( 0, { json.dumps( diagnostics ) } )' )
+ ] )
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleLine_Repl_3_test():
- # Replace with equal range
- result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
- start, end = _BuildLocations( 1, 6, 1, 8 )
- vimsupport.ReplaceChunk( start, end, 'be', result_buffer )
+ @patch( 'vim.eval', new_callable = ExtendedMock )
+ def test_SetLocationList_NotCurrent( self, vim_eval ):
+ diagnostics = [ {
+ 'bufnr': 3,
+ 'filename': 'some_filename',
+ 'lnum': 5,
+ 'col': 22,
+ 'type': 'E',
+ 'valid': 1
+ } ]
+ current_buffer = VimBuffer( '/test', number = 3 )
+ other_buffer = VimBuffer( '/notcurrent', number = 1 )
+ with MockVimBuffers( [ current_buffer, other_buffer ],
+ [ current_buffer, other_buffer ],
+ ( 1, 1 ) ):
+ vimsupport.SetLocationList( diagnostics )
+
+ # This version does not check the current
+ # buffer and just sets the current win
+ vim_eval.assert_has_exact_calls( [
+ call( f'setloclist( 0, { json.dumps( diagnostics ) } )' )
+ ] )
- AssertBuffersAreEqualAsBytes( [ 'This be a string' ], result_buffer )
+ @patch( 'ycm.vimsupport.VariableExists', return_value = True )
+ @patch( 'ycm.vimsupport.SetFittingHeightForCurrentWindow' )
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ def test_OpenLocationList(
+ self, vim_command, fitting_height, variable_exists ):
+ vimsupport.OpenLocationList( focus = False, autoclose = True )
+ vim_command.assert_has_exact_calls( [
+ call( 'lopen' ),
+ call( 'augroup ycmlocation' ),
+ call( 'autocmd! * ' ),
+ call( 'autocmd WinLeave '
+ 'if bufnr( "%" ) == expand( "" ) | q | endif '
+ '| autocmd! ycmlocation' ),
+ call( 'augroup END' ),
+ call( 'doautocmd User YcmLocationOpened' ),
+ call( 'silent! wincmd p' )
+ ] )
+ fitting_height.assert_called_once_with()
+ variable_exists.assert_called_once_with( '#User#YcmLocationOpened' )
+
+
+ @patch( 'vim.command' )
+ def test_SetFittingHeightForCurrentWindow_LineWrapOn(
+ self, vim_command, *args ):
+ # Create a two lines buffer whose first
+ # line is longer than the window width.
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'a' * 140, 'b' * 80 ] )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
+ vim.current.window.width = 120
+ vim.current.window.options[ 'wrap' ] = True
+ vimsupport.SetFittingHeightForCurrentWindow()
+ vim_command.assert_called_once_with( '3wincmd _' )
+
+
+ @patch( 'vim.command' )
+ def test_SetFittingHeightForCurrentWindow_NoResize(
+ self, vim_command, *args ):
+ # Create a two lines buffer whose first
+ # line is longer than the window width.
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'a' * 140, 'b' * 80 ],
+ vars = { 'ycm_no_resize': 1 } )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
+ vim.current.window.width = 120
+ vim.current.window.options[ 'wrap' ] = True
+ vimsupport.SetFittingHeightForCurrentWindow()
+ vim_command.assert_not_called()
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleLine_Add_1_test():
- # Insert at start
- result_buffer = VimBuffer( 'buffer', contents = [ 'is a string' ] )
- start, end = _BuildLocations( 1, 1, 1, 1 )
- vimsupport.ReplaceChunk( start, end, 'This ', result_buffer )
- AssertBuffersAreEqualAsBytes( [ 'This is a string' ], result_buffer )
+ @patch( 'vim.command' )
+ def test_SetFittingHeightForCurrentWindow_LineWrapOff(
+ self, vim_command, *args ):
+ # Create a two lines buffer whose first
+ # line is longer than the window width.
+ current_buffer = VimBuffer( 'buffer',
+ contents = [ 'a' * 140, 'b' * 80 ] )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
+ vim.current.window.width = 120
+ vim.current.window.options[ 'wrap' ] = False
+ vimsupport.SetFittingHeightForCurrentWindow()
+ vim_command.assert_called_once_with( '2wincmd _' )
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleLine_Add_2_test():
- # Insert at end
- result_buffer = VimBuffer( 'buffer', contents = [ 'This is a ' ] )
- start, end = _BuildLocations( 1, 11, 1, 11 )
- vimsupport.ReplaceChunk( start, end, 'string', result_buffer )
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleLine_Repl_1( self ):
+ # Replace with longer range
+ result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
+ start, end = _BuildLocations( 1, 11, 1, 17 )
+ vimsupport.ReplaceChunk( start, end, 'pie', result_buffer )
- AssertBuffersAreEqualAsBytes( [ 'This is a string' ], result_buffer )
+ AssertBuffersAreEqualAsBytes( [ 'This is a pie' ], result_buffer )
+ # and replace again
+ start, end = _BuildLocations( 1, 10, 1, 11 )
+ vimsupport.ReplaceChunk( start, end, ' piece of ', result_buffer )
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleLine_Add_3_test():
- # Insert in the middle
- result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
- start, end = _BuildLocations( 1, 8, 1, 8 )
- vimsupport.ReplaceChunk( start, end, ' not', result_buffer )
+ AssertBuffersAreEqualAsBytes( [ 'This is a piece of pie' ], result_buffer )
- AssertBuffersAreEqualAsBytes( [ 'This is not a string' ], result_buffer )
+ # and once more, for luck
+ start, end = _BuildLocations( 1, 1, 1, 5 )
+ vimsupport.ReplaceChunk( start, end, 'How long', result_buffer )
+ AssertBuffersAreEqualAsBytes( [ 'How long is a piece of pie' ],
+ result_buffer )
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleLine_Del_1_test():
- # Delete from start
- result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
- start, end = _BuildLocations( 1, 1, 1, 6 )
- vimsupport.ReplaceChunk( start, end, '', result_buffer )
- AssertBuffersAreEqualAsBytes( [ 'is a string' ], result_buffer )
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleLine_Repl_2( self ):
+ # Replace with shorter range
+ result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
+ start, end = _BuildLocations( 1, 11, 1, 17 )
+ vimsupport.ReplaceChunk( start, end, 'test', result_buffer )
+ AssertBuffersAreEqualAsBytes( [ 'This is a test' ], result_buffer )
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleLine_Del_2_test():
- # Delete from end
- result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
- start, end = _BuildLocations( 1, 10, 1, 18 )
- vimsupport.ReplaceChunk( start, end, '', result_buffer )
- AssertBuffersAreEqualAsBytes( [ 'This is a' ], result_buffer )
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleLine_Repl_3( self ):
+ # Replace with equal range
+ result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
+ start, end = _BuildLocations( 1, 6, 1, 8 )
+ vimsupport.ReplaceChunk( start, end, 'be', result_buffer )
+ AssertBuffersAreEqualAsBytes( [ 'This be a string' ], result_buffer )
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleLine_Del_3_test():
- # Delete from middle
- result_buffer = VimBuffer( 'buffer', contents = [ 'This is not a string' ] )
- start, end = _BuildLocations( 1, 9, 1, 13 )
- vimsupport.ReplaceChunk( start, end, '', result_buffer )
- AssertBuffersAreEqualAsBytes( [ 'This is a string' ], result_buffer )
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleLine_Add_1( self ):
+ # Insert at start
+ result_buffer = VimBuffer( 'buffer', contents = [ 'is a string' ] )
+ start, end = _BuildLocations( 1, 1, 1, 1 )
+ vimsupport.ReplaceChunk( start, end, 'This ', result_buffer )
+ AssertBuffersAreEqualAsBytes( [ 'This is a string' ], result_buffer )
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleLine_Unicode_ReplaceUnicodeChars_test():
- # Replace Unicode characters.
- result_buffer = VimBuffer(
- 'buffer', contents = [ 'This Uniçø∂‰ string is in the middle' ] )
- start, end = _BuildLocations( 1, 6, 1, 20 )
- vimsupport.ReplaceChunk( start, end, 'Unicode ', result_buffer )
- AssertBuffersAreEqualAsBytes( [ 'This Unicode string is in the middle' ],
- result_buffer )
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleLine_Add_2( self ):
+ # Insert at end
+ result_buffer = VimBuffer( 'buffer', contents = [ 'This is a ' ] )
+ start, end = _BuildLocations( 1, 11, 1, 11 )
+ vimsupport.ReplaceChunk( start, end, 'string', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'This is a string' ], result_buffer )
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleLine_Unicode_ReplaceAfterUnicode_test():
- # Replace ASCII characters after Unicode characters in the line.
- result_buffer = VimBuffer(
- 'buffer', contents = [ 'This Uniçø∂‰ string is in the middle' ] )
- start, end = _BuildLocations( 1, 30, 1, 43 )
- vimsupport.ReplaceChunk( start, end, 'fåke', result_buffer )
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleLine_Add_3( self ):
+ # Insert in the middle
+ result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
+ start, end = _BuildLocations( 1, 8, 1, 8 )
+ vimsupport.ReplaceChunk( start, end, ' not', result_buffer )
- AssertBuffersAreEqualAsBytes( [ 'This Uniçø∂‰ string is fåke' ],
- result_buffer )
+ AssertBuffersAreEqualAsBytes( [ 'This is not a string' ], result_buffer )
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleLine_Unicode_Grown_test():
- # Replace ASCII characters after Unicode characters in the line.
- result_buffer = VimBuffer( 'buffer', contents = [ 'a' ] )
- start, end = _BuildLocations( 1, 1, 1, 2 )
- vimsupport.ReplaceChunk( start, end, 'å', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'å' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_RemoveSingleLine_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
- 'aBa',
- 'aCa' ] )
- start, end = _BuildLocations( 2, 1, 3, 1 )
- vimsupport.ReplaceChunk( start, end, '', result_buffer )
- # First line is not affected.
- AssertBuffersAreEqualAsBytes( [ 'aAa',
- 'aCa' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleToMultipleLines_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
- 'aBa',
- 'aCa' ] )
- start, end = _BuildLocations( 2, 3, 2, 4 )
- vimsupport.ReplaceChunk( start, end, 'cccc', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aAa',
- 'aBcccc',
- 'aCa' ], result_buffer )
-
- # now make another change to the second line
- start, end = _BuildLocations( 2, 2, 2, 2 )
- vimsupport.ReplaceChunk( start, end, 'Eb\nbF', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aAa',
- 'aEb',
- 'bFBcccc',
- 'aCa' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleToMultipleLines2_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
- 'aBa',
- 'aCa' ] )
- start, end = _BuildLocations( 2, 2, 2, 2 )
- vimsupport.ReplaceChunk( start, end, 'Eb\nbFb\nG', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aAa',
- 'aEb',
- 'bFb',
- 'GBa',
- 'aCa' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleToMultipleLines3_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
- 'aBa',
- 'aCa' ] )
- start, end = _BuildLocations( 2, 2, 2, 2 )
- vimsupport.ReplaceChunk( start, end, 'Eb\nbFb\nbGb', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aAa',
- 'aEb',
- 'bFb',
- 'bGbBa',
- 'aCa' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleToMultipleLinesReplace_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
- 'aBa',
- 'aCa' ] )
- start, end = _BuildLocations( 1, 2, 1, 4 )
- vimsupport.ReplaceChunk( start, end, 'Eb\nbFb\nbGb', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aEb',
- 'bFb',
- 'bGb',
- 'aBa',
- 'aCa' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SingleToMultipleLinesReplace_2_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
- 'aBa',
- 'aCa' ] )
- start, end = _BuildLocations( 1, 4, 1, 4 )
- vimsupport.ReplaceChunk( start, end, 'cccc', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aAacccc',
- 'aBa',
- 'aCa', ], result_buffer )
-
- # now do a subsequent change (insert in the middle of the first line)
- start, end = _BuildLocations( 1, 2, 1, 4 )
- vimsupport.ReplaceChunk( start, end, 'Eb\nbFb\nbGb', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aEb',
- 'bFb',
- 'bGbcccc',
- 'aBa',
- 'aCa' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_MultipleLinesToSingleLine_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
- 'aBa',
- 'aCaaaa' ] )
- start, end = _BuildLocations( 3, 4, 3, 5 )
- vimsupport.ReplaceChunk( start, end, 'dd\ndd', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aAa',
- 'aBa',
- 'aCadd',
- 'ddaa' ], result_buffer )
-
- # make another modification applying offsets
- start, end = _BuildLocations( 3, 3, 3, 4 )
- vimsupport.ReplaceChunk( start, end, 'cccc', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aAa',
- 'aBa',
- 'aCccccdd',
- 'ddaa' ], result_buffer )
-
- # and another, for luck
- start, end = _BuildLocations( 2, 2, 3, 2 )
- vimsupport.ReplaceChunk( start, end, 'E', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aAa',
- 'aECccccdd',
- 'ddaa' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_MultipleLinesToSameMultipleLines_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
- 'aBa',
- 'aCa',
- 'aDe' ] )
- start, end = _BuildLocations( 2, 2, 3, 2 )
- vimsupport.ReplaceChunk( start, end, 'Eb\nbF', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aAa',
- 'aEb',
- 'bFCa',
- 'aDe' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_MultipleLinesToMoreMultipleLines_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
- 'aBa',
- 'aCa',
- 'aDe' ] )
- start, end = _BuildLocations( 2, 2, 3, 2 )
- vimsupport.ReplaceChunk( start, end, 'Eb\nbFb\nbG', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aAa',
- 'aEb',
- 'bFb',
- 'bGCa',
- 'aDe' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_MultipleLinesToLessMultipleLines_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
- 'aBa',
- 'aCa',
- 'aDe' ] )
- start, end = _BuildLocations( 1, 2, 3, 2 )
- vimsupport.ReplaceChunk( start, end, 'Eb\nbF', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aEb',
- 'bFCa',
- 'aDe' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_MultipleLinesToEvenLessMultipleLines_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
- 'aBa',
- 'aCa',
- 'aDe' ] )
- start, end = _BuildLocations( 1, 2, 4, 2 )
- vimsupport.ReplaceChunk( start, end, 'Eb\nbF', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aEb',
- 'bFDe' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_SpanBufferEdge_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
- 'aBa',
- 'aCa' ] )
- start, end = _BuildLocations( 1, 1, 1, 3 )
- vimsupport.ReplaceChunk( start, end, 'bDb', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'bDba',
- 'aBa',
- 'aCa' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_DeleteTextInLine_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
- 'aBa',
- 'aCa' ] )
- start, end = _BuildLocations( 2, 2, 2, 3 )
- vimsupport.ReplaceChunk( start, end, '', result_buffer )
- AssertBuffersAreEqualAsBytes( [ 'aAa',
- 'aa',
- 'aCa' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_AddTextInLine_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
- 'aBa',
- 'aCa' ] )
- start, end = _BuildLocations( 2, 2, 2, 2 )
- vimsupport.ReplaceChunk( start, end, 'bDb', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aAa',
- 'abDbBa',
- 'aCa' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_ReplaceTextInLine_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
- 'aBa',
- 'aCa' ] )
- start, end = _BuildLocations( 2, 2, 2, 3 )
- vimsupport.ReplaceChunk( start, end, 'bDb', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'aAa',
- 'abDba',
- 'aCa' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_NewlineChunk_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'first line',
- 'second line' ] )
- start, end = _BuildLocations( 1, 11, 2, 1 )
- vimsupport.ReplaceChunk( start, end, '\n', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'first line',
- 'second line' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunk_BeyondEndOfFile_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'first line',
- 'second line' ] )
- start, end = _BuildLocations( 1, 11, 3, 1 )
- vimsupport.ReplaceChunk( start, end, '\n', result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'first line' ], result_buffer )
-
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleLine_Del_1( self ):
+ # Delete from start
+ result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
+ start, end = _BuildLocations( 1, 1, 1, 6 )
+ vimsupport.ReplaceChunk( start, end, '', result_buffer )
-@patch( 'vim.current.window.cursor', ( 1, 3 ) )
-def ReplaceChunk_CursorPosition_test():
- result_buffer = VimBuffer( 'buffer', contents = [ 'bar' ] )
- start, end = _BuildLocations( 1, 1, 1, 1 )
- vimsupport.ReplaceChunk( start,
- end,
- 'xyz\nfoo',
- result_buffer )
+ AssertBuffersAreEqualAsBytes( [ 'is a string' ], result_buffer )
- AssertBuffersAreEqualAsBytes( [ 'xyz', 'foobar' ], result_buffer )
- # Cursor line is 0-based.
- assert_that( vimsupport.CurrentLineAndColumn(), contains_exactly( 1, 6 ) )
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleLine_Del_2( self ):
+ # Delete from end
+ result_buffer = VimBuffer( 'buffer', contents = [ 'This is a string' ] )
+ start, end = _BuildLocations( 1, 10, 1, 18 )
+ vimsupport.ReplaceChunk( start, end, '', result_buffer )
-def _BuildLocations( start_line, start_column, end_line, end_column ):
- return {
- 'line_num' : start_line,
- 'column_num': start_column,
- }, {
- 'line_num' : end_line,
- 'column_num': end_column,
- }
+ AssertBuffersAreEqualAsBytes( [ 'This is a' ], result_buffer )
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunksInBuffer_SortedChunks_test():
- chunks = [
- _BuildChunk( 1, 4, 1, 4, '(' ),
- _BuildChunk( 1, 11, 1, 11, ')' )
- ]
-
- result_buffer = VimBuffer( 'buffer', contents = [ 'CT<10 >> 2> ct' ] )
- vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'CT<(10 >> 2)> ct' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunksInBuffer_UnsortedChunks_test():
- chunks = [
- _BuildChunk( 1, 11, 1, 11, ')' ),
- _BuildChunk( 1, 4, 1, 4, '(' )
- ]
-
- result_buffer = VimBuffer( 'buffer', contents = [ 'CT<10 >> 2> ct' ] )
- vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'CT<(10 >> 2)> ct' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunksInBuffer_LineOverlappingChunks_test():
- chunks = [
- _BuildChunk( 1, 11, 2, 1, '\n ' ),
- _BuildChunk( 2, 12, 3, 1, '\n ' ),
- _BuildChunk( 3, 11, 4, 1, '\n ' )
- ]
-
- result_buffer = VimBuffer( 'buffer', contents = [ 'first line',
- 'second line',
- 'third line',
- 'fourth line' ] )
- vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'first line',
- ' second line',
- ' third line',
- ' fourth line' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunksInBuffer_OutdentChunks_test():
- chunks = [
- _BuildChunk( 1, 1, 1, 5, ' ' ),
- _BuildChunk( 1, 15, 2, 9, '\n ' ),
- _BuildChunk( 2, 20, 3, 3, '\n' )
- ]
-
- result_buffer = VimBuffer( 'buffer', contents = [ ' first line',
- ' second line',
- ' third line' ] )
- vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ ' first line',
- ' second line',
- ' third line' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunksInBuffer_OneLineIndentingChunks_test():
- chunks = [
- _BuildChunk( 1, 8, 2, 1, '\n ' ),
- _BuildChunk( 2, 9, 2, 10, '\n ' ),
- _BuildChunk( 2, 19, 2, 20, '\n ' )
- ]
-
- result_buffer = VimBuffer( 'buffer', contents = [ 'class {',
- 'method { statement }',
- '}' ] )
- vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'class {',
- ' method {',
- ' statement',
- ' }',
- '}' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-def ReplaceChunksInBuffer_SameLocation_test():
- chunks = [
- _BuildChunk( 1, 1, 1, 1, 'this ' ),
- _BuildChunk( 1, 1, 1, 1, 'is ' ),
- _BuildChunk( 1, 1, 1, 1, 'pure ' )
- ]
-
- result_buffer = VimBuffer( 'buffer', contents = [ 'folly' ] )
- vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
-
- AssertBuffersAreEqualAsBytes( [ 'this is pure folly' ], result_buffer )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-@patch( 'ycm.vimsupport.VariableExists', return_value = False )
-@patch( 'ycm.vimsupport.SetFittingHeightForCurrentWindow' )
-@patch( 'ycm.vimsupport.GetBufferNumberForFilename',
- return_value = 1,
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.BufferIsVisible',
- return_value = True,
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.OpenFilename' )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-@patch( 'vim.eval', new_callable = ExtendedMock )
-@patch( 'vim.command', new_callable = ExtendedMock )
-def ReplaceChunks_SingleFile_Open_test( vim_command,
- vim_eval,
- post_vim_message,
- open_filename,
- buffer_is_visible,
- get_buffer_number_for_filename,
- set_fitting_height,
- variable_exists ):
- single_buffer_name = os.path.realpath( 'single_file' )
-
- chunks = [
- _BuildChunk( 1, 1, 2, 1, 'replacement', single_buffer_name )
- ]
-
- result_buffer = VimBuffer(
- single_buffer_name,
- contents = [
- 'line1',
- 'line2',
- 'line3'
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleLine_Del_3( self ):
+ # Delete from middle
+ result_buffer = VimBuffer( 'buffer', contents = [ 'This is not a string' ] )
+ start, end = _BuildLocations( 1, 9, 1, 13 )
+ vimsupport.ReplaceChunk( start, end, '', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'This is a string' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleLine_Unicode_ReplaceUnicodeChars( self ):
+ # Replace Unicode characters.
+ result_buffer = VimBuffer(
+ 'buffer', contents = [ 'This Uniçø∂‰ string is in the middle' ] )
+ start, end = _BuildLocations( 1, 6, 1, 20 )
+ vimsupport.ReplaceChunk( start, end, 'Unicode ', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'This Unicode string is in the middle' ],
+ result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleLine_Unicode_ReplaceAfterUnicode( self ):
+ # Replace ASCII characters after Unicode characters in the line.
+ result_buffer = VimBuffer(
+ 'buffer', contents = [ 'This Uniçø∂‰ string is in the middle' ] )
+ start, end = _BuildLocations( 1, 30, 1, 43 )
+ vimsupport.ReplaceChunk( start, end, 'fåke', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'This Uniçø∂‰ string is fåke' ],
+ result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleLine_Unicode_Grown( self ):
+ # Replace ASCII characters after Unicode characters in the line.
+ result_buffer = VimBuffer( 'buffer', contents = [ 'a' ] )
+ start, end = _BuildLocations( 1, 1, 1, 2 )
+ vimsupport.ReplaceChunk( start, end, 'å', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'å' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_RemoveSingleLine( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
+ 'aBa',
+ 'aCa' ] )
+ start, end = _BuildLocations( 2, 1, 3, 1 )
+ vimsupport.ReplaceChunk( start, end, '', result_buffer )
+ # First line is not affected.
+ AssertBuffersAreEqualAsBytes( [ 'aAa',
+ 'aCa' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleToMultipleLines( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
+ 'aBa',
+ 'aCa' ] )
+ start, end = _BuildLocations( 2, 3, 2, 4 )
+ vimsupport.ReplaceChunk( start, end, 'cccc', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aAa',
+ 'aBcccc',
+ 'aCa' ], result_buffer )
+
+ # now make another change to the second line
+ start, end = _BuildLocations( 2, 2, 2, 2 )
+ vimsupport.ReplaceChunk( start, end, 'Eb\nbF', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aAa',
+ 'aEb',
+ 'bFBcccc',
+ 'aCa' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleToMultipleLines2( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
+ 'aBa',
+ 'aCa' ] )
+ start, end = _BuildLocations( 2, 2, 2, 2 )
+ vimsupport.ReplaceChunk( start, end, 'Eb\nbFb\nG', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aAa',
+ 'aEb',
+ 'bFb',
+ 'GBa',
+ 'aCa' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleToMultipleLines3( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
+ 'aBa',
+ 'aCa' ] )
+ start, end = _BuildLocations( 2, 2, 2, 2 )
+ vimsupport.ReplaceChunk( start, end, 'Eb\nbFb\nbGb', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aAa',
+ 'aEb',
+ 'bFb',
+ 'bGbBa',
+ 'aCa' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleToMultipleLinesReplace( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
+ 'aBa',
+ 'aCa' ] )
+ start, end = _BuildLocations( 1, 2, 1, 4 )
+ vimsupport.ReplaceChunk( start, end, 'Eb\nbFb\nbGb', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aEb',
+ 'bFb',
+ 'bGb',
+ 'aBa',
+ 'aCa' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SingleToMultipleLinesReplace_2( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
+ 'aBa',
+ 'aCa' ] )
+ start, end = _BuildLocations( 1, 4, 1, 4 )
+ vimsupport.ReplaceChunk( start, end, 'cccc', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aAacccc',
+ 'aBa',
+ 'aCa', ], result_buffer )
+
+ # now do a subsequent change (insert in the middle of the first line)
+ start, end = _BuildLocations( 1, 2, 1, 4 )
+ vimsupport.ReplaceChunk( start, end, 'Eb\nbFb\nbGb', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aEb',
+ 'bFb',
+ 'bGbcccc',
+ 'aBa',
+ 'aCa' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_MultipleLinesToSingleLine( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
+ 'aBa',
+ 'aCaaaa' ] )
+ start, end = _BuildLocations( 3, 4, 3, 5 )
+ vimsupport.ReplaceChunk( start, end, 'dd\ndd', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aAa',
+ 'aBa',
+ 'aCadd',
+ 'ddaa' ], result_buffer )
+
+ # make another modification applying offsets
+ start, end = _BuildLocations( 3, 3, 3, 4 )
+ vimsupport.ReplaceChunk( start, end, 'cccc', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aAa',
+ 'aBa',
+ 'aCccccdd',
+ 'ddaa' ], result_buffer )
+
+ # and another, for luck
+ start, end = _BuildLocations( 2, 2, 3, 2 )
+ vimsupport.ReplaceChunk( start, end, 'E', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aAa',
+ 'aECccccdd',
+ 'ddaa' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_MultipleLinesToSameMultipleLines( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
+ 'aBa',
+ 'aCa',
+ 'aDe' ] )
+ start, end = _BuildLocations( 2, 2, 3, 2 )
+ vimsupport.ReplaceChunk( start, end, 'Eb\nbF', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aAa',
+ 'aEb',
+ 'bFCa',
+ 'aDe' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_MultipleLinesToMoreMultipleLines( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
+ 'aBa',
+ 'aCa',
+ 'aDe' ] )
+ start, end = _BuildLocations( 2, 2, 3, 2 )
+ vimsupport.ReplaceChunk( start, end, 'Eb\nbFb\nbG', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aAa',
+ 'aEb',
+ 'bFb',
+ 'bGCa',
+ 'aDe' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_MultipleLinesToLessMultipleLines( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
+ 'aBa',
+ 'aCa',
+ 'aDe' ] )
+ start, end = _BuildLocations( 1, 2, 3, 2 )
+ vimsupport.ReplaceChunk( start, end, 'Eb\nbF', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aEb',
+ 'bFCa',
+ 'aDe' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_MultipleLinesToEvenLessMultipleLines( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
+ 'aBa',
+ 'aCa',
+ 'aDe' ] )
+ start, end = _BuildLocations( 1, 2, 4, 2 )
+ vimsupport.ReplaceChunk( start, end, 'Eb\nbF', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aEb',
+ 'bFDe' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_SpanBufferEdge( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
+ 'aBa',
+ 'aCa' ] )
+ start, end = _BuildLocations( 1, 1, 1, 3 )
+ vimsupport.ReplaceChunk( start, end, 'bDb', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'bDba',
+ 'aBa',
+ 'aCa' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_DeleteTextInLine( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
+ 'aBa',
+ 'aCa' ] )
+ start, end = _BuildLocations( 2, 2, 2, 3 )
+ vimsupport.ReplaceChunk( start, end, '', result_buffer )
+ AssertBuffersAreEqualAsBytes( [ 'aAa',
+ 'aa',
+ 'aCa' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_AddTextInLine( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
+ 'aBa',
+ 'aCa' ] )
+ start, end = _BuildLocations( 2, 2, 2, 2 )
+ vimsupport.ReplaceChunk( start, end, 'bDb', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aAa',
+ 'abDbBa',
+ 'aCa' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_ReplaceTextInLine( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'aAa',
+ 'aBa',
+ 'aCa' ] )
+ start, end = _BuildLocations( 2, 2, 2, 3 )
+ vimsupport.ReplaceChunk( start, end, 'bDb', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'aAa',
+ 'abDba',
+ 'aCa' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_NewlineChunk( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'first line',
+ 'second line' ] )
+ start, end = _BuildLocations( 1, 11, 2, 1 )
+ vimsupport.ReplaceChunk( start, end, '\n', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'first line',
+ 'second line' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunk_BeyondEndOfFile( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'first line',
+ 'second line' ] )
+ start, end = _BuildLocations( 1, 11, 3, 1 )
+ vimsupport.ReplaceChunk( start, end, '\n', result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'first line' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 3 ) )
+ def test_ReplaceChunk_CursorPosition( self ):
+ result_buffer = VimBuffer( 'buffer', contents = [ 'bar' ] )
+ start, end = _BuildLocations( 1, 1, 1, 1 )
+ vimsupport.ReplaceChunk( start,
+ end,
+ 'xyz\nfoo',
+ result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'xyz', 'foobar' ], result_buffer )
+ # Cursor line is 0-based.
+ assert_that( vimsupport.CurrentLineAndColumn(), contains_exactly( 1, 6 ) )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunksInBuffer_SortedChunks( self ):
+ chunks = [
+ _BuildChunk( 1, 4, 1, 4, '(' ),
+ _BuildChunk( 1, 11, 1, 11, ')' )
]
- )
-
- with patch( 'vim.buffers', [ None, result_buffer, None ] ):
- vimsupport.ReplaceChunks( chunks )
-
- # Ensure that we applied the replacement correctly
- assert_that( result_buffer.GetLines(), contains_exactly(
- 'replacementline2',
- 'line3',
- ) )
-
- # GetBufferNumberForFilename is called twice:
- # - once to the check if we would require opening the file (so that we can
- # raise a warning)
- # - once whilst applying the changes
- get_buffer_number_for_filename.assert_has_exact_calls( [
- call( single_buffer_name ),
- call( single_buffer_name ),
- ] )
-
- # BufferIsVisible is called twice for the same reasons as above
- buffer_is_visible.assert_has_exact_calls( [
- call( 1 ),
- call( 1 ),
- ] )
-
- # we don't attempt to open any files
- open_filename.assert_not_called()
-
- qflist = json.dumps( [ {
- 'bufnr': 1,
- 'filename': single_buffer_name,
- 'lnum': 1,
- 'col': 1,
- 'text': 'replacement',
- 'type': 'F'
- } ] )
- # But we do set the quickfix list
- vim_eval.assert_has_exact_calls( [
- call( f'setqflist( { qflist } )' )
- ] )
-
- # And it is ReplaceChunks that prints the message showing the number of
- # changes
- post_vim_message.assert_has_exact_calls( [
- call( 'Applied 1 changes', warning = False ),
- ] )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-@patch( 'ycm.vimsupport.VariableExists', return_value = False )
-@patch( 'ycm.vimsupport.SetFittingHeightForCurrentWindow' )
-@patch( 'ycm.vimsupport.GetBufferNumberForFilename',
- side_effect = [ -1, -1, 1 ],
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.BufferIsVisible',
- side_effect = [ False, False, True ],
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.OpenFilename',
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.Confirm',
- return_value = True,
- new_callable = ExtendedMock )
-@patch( 'vim.eval', return_value = 10, new_callable = ExtendedMock )
-@patch( 'vim.command', new_callable = ExtendedMock )
-def ReplaceChunks_SingleFile_NotOpen_test( vim_command,
- vim_eval,
- confirm,
- post_vim_message,
- open_filename,
- buffer_is_visible,
- get_buffer_number_for_filename,
- set_fitting_height,
- variable_exists ):
- single_buffer_name = os.path.realpath( 'single_file' )
-
- chunks = [
- _BuildChunk( 1, 1, 2, 1, 'replacement', single_buffer_name )
- ]
-
- result_buffer = VimBuffer(
- single_buffer_name,
- contents = [
- 'line1',
- 'line2',
- 'line3'
+
+ result_buffer = VimBuffer( 'buffer', contents = [ 'CT<10 >> 2> ct' ] )
+ vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'CT<(10 >> 2)> ct' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunksInBuffer_UnsortedChunks( self ):
+ chunks = [
+ _BuildChunk( 1, 11, 1, 11, ')' ),
+ _BuildChunk( 1, 4, 1, 4, '(' )
]
- )
-
- with patch( 'vim.buffers', [ None, result_buffer, None ] ):
- vimsupport.ReplaceChunks( chunks )
-
- # We checked if it was OK to open the file
- confirm.assert_has_exact_calls( [
- call( vimsupport.FIXIT_OPENING_BUFFERS_MESSAGE_FORMAT.format( 1 ) )
- ] )
-
- # Ensure that we applied the replacement correctly
- assert_that( result_buffer.GetLines(), contains_exactly(
- 'replacementline2',
- 'line3',
- ) )
-
- # GetBufferNumberForFilename is called 3 times. The return values are set in
- # the @patch call above:
- # - once to the check if we would require opening the file (so that we can
- # raise a warning) (-1 return)
- # - once whilst applying the changes (-1 return)
- # - finally after calling OpenFilename (1 return)
- get_buffer_number_for_filename.assert_has_exact_calls( [
- call( single_buffer_name ),
- call( single_buffer_name ),
- call( single_buffer_name ),
- ] )
-
- # BufferIsVisible is called 3 times for the same reasons as above, with the
- # return of each one
- buffer_is_visible.assert_has_exact_calls( [
- call( -1 ),
- call( -1 ),
- call( 1 ),
- ] )
-
- # We open 'single_file' as expected.
- open_filename.assert_called_with( single_buffer_name, {
- 'focus': True,
- 'fix': True,
- 'size': 10
- } )
-
- # And close it again, then show the quickfix window.
- vim_command.assert_has_exact_calls( [
- call( 'lclose' ),
- call( 'hide' ),
- ] )
-
- qflist = json.dumps( [ {
- 'bufnr': 1,
- 'filename': single_buffer_name,
- 'lnum': 1,
- 'col': 1,
- 'text': 'replacement',
- 'type': 'F'
- } ] )
- # And update the quickfix list
- vim_eval.assert_has_exact_calls( [
- call( '&previewheight' ),
- call( f'setqflist( { qflist } )' )
- ] )
-
- # And it is ReplaceChunks that prints the message showing the number of
- # changes
- post_vim_message.assert_has_exact_calls( [
- call( 'Applied 1 changes', warning = False ),
- ] )
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-@patch( 'ycm.vimsupport.VariableExists', return_value = False )
-@patch( 'ycm.vimsupport.SetFittingHeightForCurrentWindow' )
-@patch( 'ycm.vimsupport.GetBufferNumberForFilename',
- side_effect = [ -1, 1 ],
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.BufferIsVisible',
- side_effect = [ False, True ],
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.OpenFilename',
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.Confirm',
- return_value = True,
- new_callable = ExtendedMock )
-@patch( 'vim.eval', return_value = 10, new_callable = ExtendedMock )
-@patch( 'vim.command', new_callable = ExtendedMock )
-def ReplaceChunks_SingleFile_NotOpen_Silent_test(
- vim_command,
- vim_eval,
- confirm,
- post_vim_message,
- open_filename,
- buffer_is_visible,
- get_buffer_number_for_filename,
- set_fitting_height,
- variable_exists ):
-
- # This test is the same as ReplaceChunks_SingleFile_NotOpen_test, but we pass
- # the silent flag, as used by post-complete actions, and shows the stuff we
- # _don't_ call in that case.
-
- single_buffer_name = os.path.realpath( 'single_file' )
-
- chunks = [
- _BuildChunk( 1, 1, 2, 1, 'replacement', single_buffer_name )
- ]
-
- result_buffer = VimBuffer(
- single_buffer_name,
- contents = [
- 'line1',
- 'line2',
- 'line3'
+
+ result_buffer = VimBuffer( 'buffer', contents = [ 'CT<10 >> 2> ct' ] )
+ vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'CT<(10 >> 2)> ct' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunksInBuffer_LineOverlappingChunks( self ):
+ chunks = [
+ _BuildChunk( 1, 11, 2, 1, '\n ' ),
+ _BuildChunk( 2, 12, 3, 1, '\n ' ),
+ _BuildChunk( 3, 11, 4, 1, '\n ' )
]
- )
-
- with patch( 'vim.buffers', [ None, result_buffer, None ] ):
- vimsupport.ReplaceChunks( chunks, silent=True )
-
- # We didn't check if it was OK to open the file (silent)
- confirm.assert_not_called()
-
- # Ensure that we applied the replacement correctly
- assert_that( result_buffer.GetLines(), contains_exactly(
- 'replacementline2',
- 'line3',
- ) )
-
- # GetBufferNumberForFilename is called 2 times. The return values are set in
- # the @patch call above:
- # - once whilst applying the changes (-1 return)
- # - finally after calling OpenFilename (1 return)
- get_buffer_number_for_filename.assert_has_exact_calls( [
- call( single_buffer_name ),
- call( single_buffer_name ),
- ] )
-
- # BufferIsVisible is called 2 times for the same reasons as above, with the
- # return of each one
- buffer_is_visible.assert_has_exact_calls( [
- call( -1 ),
- call( 1 ),
- ] )
-
- # We open 'single_file' as expected.
- open_filename.assert_called_with( single_buffer_name, {
- 'focus': True,
- 'fix': True,
- 'size': 10
- } )
-
- # And close it again, but don't show the quickfix window
- vim_command.assert_has_exact_calls( [
- call( 'lclose' ),
- call( 'hide' ),
- ] )
- set_fitting_height.assert_not_called()
-
- # But we _don't_ update the QuickFix list
- vim_eval.assert_has_exact_calls( [
- call( '&previewheight' ),
- ] )
-
- # And we don't print a message either
- post_vim_message.assert_not_called()
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-@patch( 'ycm.vimsupport.GetBufferNumberForFilename',
- side_effect = [ -1, -1, 1 ],
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.BufferIsVisible',
- side_effect = [ False, False, True ],
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.OpenFilename',
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.PostVimMessage',
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.Confirm',
- return_value = False,
- new_callable = ExtendedMock )
-@patch( 'vim.eval',
- return_value = 10,
- new_callable = ExtendedMock )
-@patch( 'vim.command', new_callable = ExtendedMock )
-def ReplaceChunks_User_Declines_To_Open_File_test(
- vim_command,
- vim_eval,
- confirm,
- post_vim_message,
- open_filename,
- buffer_is_visible,
- get_buffer_number_for_filename ):
-
- # Same as above, except the user selects Cancel when asked if they should
- # allow us to open lots of (ahem, 1) file.
- single_buffer_name = os.path.realpath( 'single_file' )
-
- chunks = [
- _BuildChunk( 1, 1, 2, 1, 'replacement', single_buffer_name )
- ]
-
- result_buffer = VimBuffer(
- single_buffer_name,
- contents = [
- 'line1',
- 'line2',
- 'line3'
+
+ result_buffer = VimBuffer( 'buffer', contents = [ 'first line',
+ 'second line',
+ 'third line',
+ 'fourth line' ] )
+ vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'first line',
+ ' second line',
+ ' third line',
+ ' fourth line' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunksInBuffer_OutdentChunks( self ):
+ chunks = [
+ _BuildChunk( 1, 1, 1, 5, ' ' ),
+ _BuildChunk( 1, 15, 2, 9, '\n ' ),
+ _BuildChunk( 2, 20, 3, 3, '\n' )
]
- )
-
- with patch( 'vim.buffers', [ None, result_buffer, None ] ):
- vimsupport.ReplaceChunks( chunks )
-
- # We checked if it was OK to open the file
- confirm.assert_has_exact_calls( [
- call( vimsupport.FIXIT_OPENING_BUFFERS_MESSAGE_FORMAT.format( 1 ) )
- ] )
-
- # Ensure that buffer is not changed
- assert_that( result_buffer.GetLines(), contains_exactly(
- 'line1',
- 'line2',
- 'line3',
- ) )
-
- # GetBufferNumberForFilename is called once. The return values are set in
- # the @patch call above:
- # - once to the check if we would require opening the file (so that we can
- # raise a warning) (-1 return)
- get_buffer_number_for_filename.assert_has_exact_calls( [
- call( single_buffer_name ),
- ] )
-
- # BufferIsVisible is called once for the above file, which wasn't visible.
- buffer_is_visible.assert_has_exact_calls( [
- call( -1 ),
- ] )
-
- # We don't attempt to open any files or update any quickfix list or anything
- # like that
- open_filename.assert_not_called()
- vim_eval.assert_not_called()
- vim_command.assert_not_called()
- post_vim_message.assert_not_called()
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-@patch( 'ycm.vimsupport.GetBufferNumberForFilename',
- side_effect = [ -1, -1, 1 ],
- new_callable = ExtendedMock )
-# Key difference is here: In the final check, BufferIsVisible returns False
-@patch( 'ycm.vimsupport.BufferIsVisible',
- side_effect = [ False, False, False ],
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.OpenFilename',
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.PostVimMessage',
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.Confirm',
- return_value = True,
- new_callable = ExtendedMock )
-@patch( 'vim.eval',
- return_value = 10,
- new_callable = ExtendedMock )
-@patch( 'vim.command',
- new_callable = ExtendedMock )
-def ReplaceChunks_User_Aborts_Opening_File_test(
- vim_command,
- vim_eval,
- confirm,
- post_vim_message,
- open_filename,
- buffer_is_visible,
- get_buffer_number_for_filename ):
-
- # Same as above, except the user selects Abort or Quick during the
- # "swap-file-found" dialog
- single_buffer_name = os.path.realpath( 'single_file' )
-
- chunks = [
- _BuildChunk( 1, 1, 2, 1, 'replacement', single_buffer_name )
- ]
-
- result_buffer = VimBuffer(
- single_buffer_name,
- contents = [
- 'line1',
- 'line2',
- 'line3'
+
+ result_buffer = VimBuffer( 'buffer', contents = [ ' first line',
+ ' second line',
+ ' third line' ] )
+ vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ ' first line',
+ ' second line',
+ ' third line' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunksInBuffer_OneLineIndentingChunks( self ):
+ chunks = [
+ _BuildChunk( 1, 8, 2, 1, '\n ' ),
+ _BuildChunk( 2, 9, 2, 10, '\n ' ),
+ _BuildChunk( 2, 19, 2, 20, '\n ' )
]
- )
- with patch( 'vim.buffers', [ None, result_buffer, None ] ):
- assert_that( calling( vimsupport.ReplaceChunks ).with_args( chunks ),
- raises( RuntimeError,
- 'Unable to open file: .+single_file\n'
- 'FixIt/Refactor operation aborted prior to completion. '
- 'Your files have not been fully updated. '
- 'Please use undo commands to revert the applied changes.' ) )
-
- # We checked if it was OK to open the file
- confirm.assert_has_exact_calls( [
- call( vimsupport.FIXIT_OPENING_BUFFERS_MESSAGE_FORMAT.format( 1 ) )
- ] )
-
- # Ensure that buffer is not changed
- assert_that( result_buffer.GetLines(), contains_exactly(
- 'line1',
- 'line2',
- 'line3',
- ) )
-
- # We tried to open this file
- open_filename.assert_called_with( single_buffer_name, {
- 'focus': True,
- 'fix': True,
- 'size': 10
- } )
- vim_eval.assert_called_with( "&previewheight" )
-
- # But raised an exception before issuing the message at the end
- post_vim_message.assert_not_called()
-
-
-@patch( 'vim.current.window.cursor', ( 1, 1 ) )
-@patch( 'ycm.vimsupport.VariableExists', return_value = False )
-@patch( 'ycm.vimsupport.SetFittingHeightForCurrentWindow' )
-@patch( 'ycm.vimsupport.GetBufferNumberForFilename', side_effect = [
- 22, # first_file (check)
- -1, # second_file (check)
- 22, # first_file (apply)
- -1, # second_file (apply)
- 19, # second_file (check after open)
- ],
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.BufferIsVisible', side_effect = [
- True, # first_file (check)
- False, # second_file (check)
- True, # first_file (apply)
- False, # second_file (apply)
- True, # side_effect (check after open)
- ],
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.OpenFilename',
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.PostVimMessage',
- new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.Confirm', return_value = True,
- new_callable = ExtendedMock )
-@patch( 'vim.eval', return_value = 10,
- new_callable = ExtendedMock )
-@patch( 'vim.command',
- new_callable = ExtendedMock )
-def ReplaceChunks_MultiFile_Open_test( vim_command,
- vim_eval,
- confirm,
- post_vim_message,
- open_filename,
- buffer_is_visible,
- get_buffer_number_for_filename,
- set_fitting_height,
- variable_exists ):
-
- # Chunks are split across 2 files, one is already open, one isn't
- first_buffer_name = os.path.realpath( '1_first_file' )
- second_buffer_name = os.path.realpath( '2_second_file' )
-
- chunks = [
- _BuildChunk( 1, 1, 2, 1, 'first_file_replacement ', first_buffer_name ),
- _BuildChunk( 2, 1, 2, 1, 'second_file_replacement ', second_buffer_name ),
- ]
-
- first_file = VimBuffer(
- first_buffer_name,
- number = 22,
- contents = [
- 'line1',
- 'line2',
- 'line3',
+ result_buffer = VimBuffer( 'buffer', contents = [ 'class {',
+ 'method { statement }',
+ '}' ] )
+ vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'class {',
+ ' method {',
+ ' statement',
+ ' }',
+ '}' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ def test_ReplaceChunksInBuffer_SameLocation( self ):
+ chunks = [
+ _BuildChunk( 1, 1, 1, 1, 'this ' ),
+ _BuildChunk( 1, 1, 1, 1, 'is ' ),
+ _BuildChunk( 1, 1, 1, 1, 'pure ' )
]
- )
- second_file = VimBuffer(
- second_buffer_name,
- number = 19,
- contents = [
- 'another line1',
- 'ACME line2',
+
+ result_buffer = VimBuffer( 'buffer', contents = [ 'folly' ] )
+ vimsupport.ReplaceChunksInBuffer( chunks, result_buffer )
+
+ AssertBuffersAreEqualAsBytes( [ 'this is pure folly' ], result_buffer )
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ @patch( 'ycm.vimsupport.VariableExists', return_value = False )
+ @patch( 'ycm.vimsupport.SetFittingHeightForCurrentWindow' )
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.GetBufferNumberForFilename',
+ return_value = 1,
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.BufferIsVisible',
+ return_value = True,
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.OpenFilename' )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ @patch( 'vim.eval', new_callable = ExtendedMock )
+ def test_ReplaceChunks_SingleFile_Open( self,
+ vim_eval,
+ post_vim_message,
+ open_filename,
+ buffer_is_visible,
+ get_buffer_number_for_filename,
+ *args ):
+ single_buffer_name = os.path.realpath( 'single_file' )
+
+ chunks = [
+ _BuildChunk( 1, 1, 2, 1, 'replacement', single_buffer_name )
]
- )
-
- vim_buffers = [ None ] * 23
- vim_buffers[ 22 ] = first_file
- vim_buffers[ 19 ] = second_file
-
- with patch( 'vim.buffers', vim_buffers ):
- vimsupport.ReplaceChunks( chunks )
-
- # We checked for the right file names
- get_buffer_number_for_filename.assert_has_exact_calls( [
- call( first_buffer_name ),
- call( second_buffer_name ),
- call( first_buffer_name ),
- call( second_buffer_name ),
- call( second_buffer_name ),
- ] )
-
- # We checked if it was OK to open the file
- confirm.assert_has_exact_calls( [
- call( vimsupport.FIXIT_OPENING_BUFFERS_MESSAGE_FORMAT.format( 1 ) )
- ] )
-
- # Ensure that buffers are updated
- assert_that( second_file.GetLines(), contains_exactly(
- 'another line1',
- 'second_file_replacement ACME line2',
- ) )
- assert_that( first_file.GetLines(), contains_exactly(
- 'first_file_replacement line2',
- 'line3',
- ) )
-
- # We open '2_second_file' as expected.
- open_filename.assert_called_with( second_buffer_name, {
- 'focus': True,
- 'fix': True,
- 'size': 10
- } )
-
- # And close it again, then show the quickfix window.
- vim_command.assert_has_exact_calls( [
- call( 'lclose' ),
- call( 'hide' ),
- ] )
-
- qflist = json.dumps( [ {
- 'bufnr': 22,
- 'filename': first_buffer_name,
- 'lnum': 1,
- 'col': 1,
- 'text': 'first_file_replacement ',
- 'type': 'F'
- }, {
- 'bufnr': 19,
- 'filename': second_buffer_name,
- 'lnum': 2,
- 'col': 1,
- 'text': 'second_file_replacement ',
- 'type': 'F'
- } ] )
- # And update the quickfix list with each entry
- vim_eval.assert_has_exact_calls( [
- call( '&previewheight' ),
- call( f'setqflist( { qflist } )' )
- ] )
-
- # And it is ReplaceChunks that prints the message showing the number of
- # changes
- post_vim_message.assert_has_exact_calls( [
- call( 'Applied 2 changes', warning = False ),
- ] )
+ result_buffer = VimBuffer(
+ single_buffer_name,
+ contents = [
+ 'line1',
+ 'line2',
+ 'line3'
+ ]
+ )
-def _BuildChunk( start_line,
- start_column,
- end_line,
- end_column,
- replacement_text, filepath='test_file_name' ):
- return {
- 'range': {
- 'start': {
- 'filepath': filepath,
- 'line_num': start_line,
- 'column_num': start_column,
- },
- 'end': {
- 'filepath': filepath,
- 'line_num': end_line,
- 'column_num': end_column,
- },
- },
- 'replacement_text': replacement_text
- }
+ with patch( 'vim.buffers', [ None, result_buffer, None ] ):
+ vimsupport.ReplaceChunks( chunks )
+
+ # Ensure that we applied the replacement correctly
+ assert_that( result_buffer.GetLines(), contains_exactly(
+ 'replacementline2',
+ 'line3',
+ ) )
+
+ # GetBufferNumberForFilename is called twice:
+ # - once to the check if we would require opening the file (so that we can
+ # raise a warning)
+ # - once whilst applying the changes
+ get_buffer_number_for_filename.assert_has_exact_calls( [
+ call( single_buffer_name ),
+ call( single_buffer_name ),
+ ] )
+ # BufferIsVisible is called twice for the same reasons as above
+ buffer_is_visible.assert_has_exact_calls( [
+ call( 1 ),
+ call( 1 ),
+ ] )
-def GetDiagnosticMatchPattern_ErrorInMiddleOfLine_test():
- current_buffer = VimBuffer(
- 'some_file',
- contents = [ 'Highlight this error please' ]
- )
+ # we don't attempt to open any files
+ open_filename.assert_not_called()
+
+ qflist = json.dumps( [ {
+ 'bufnr': 1,
+ 'filename': single_buffer_name,
+ 'lnum': 1,
+ 'col': 1,
+ 'text': 'replacement',
+ 'type': 'F'
+ } ] )
+ # But we do set the quickfix list
+ vim_eval.assert_has_exact_calls( [
+ call( f'setqflist( { qflist } )' )
+ ] )
- with patch( 'vim.current.buffer', current_buffer ):
- assert_that(
- vimsupport.GetDiagnosticMatchPattern( 1, 16, 1, 21 ),
- equal_to( '\\%1l\\%16c\\_.\\{-}\\%1l\\%21c' )
- )
+ # And it is ReplaceChunks that prints the message showing the number of
+ # changes
+ post_vim_message.assert_has_exact_calls( [
+ call( 'Applied 1 changes', warning = False ),
+ ] )
-def AddDiagnosticSyntaxMatch_WarningAtEndOfLine_test():
- current_buffer = VimBuffer(
- 'some_file',
- contents = [ 'Highlight this warning' ]
- )
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ @patch( 'ycm.vimsupport.VariableExists', return_value = False )
+ @patch( 'ycm.vimsupport.SetFittingHeightForCurrentWindow' )
+ @patch( 'ycm.vimsupport.GetBufferNumberForFilename',
+ side_effect = [ -1, -1, 1 ],
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.BufferIsVisible',
+ side_effect = [ False, False, True ],
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.OpenFilename',
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.Confirm',
+ return_value = True,
+ new_callable = ExtendedMock )
+ @patch( 'vim.eval', return_value = 10, new_callable = ExtendedMock )
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ def test_ReplaceChunks_SingleFile_NotOpen( self,
+ vim_command,
+ vim_eval,
+ confirm,
+ post_vim_message,
+ open_filename,
+ buffer_is_visible,
+ get_buffer_number_for_filename,
+ set_fitting_height,
+ variable_exists ):
+ single_buffer_name = os.path.realpath( 'single_file' )
+
+ chunks = [
+ _BuildChunk( 1, 1, 2, 1, 'replacement', single_buffer_name )
+ ]
- with patch( 'vim.current.buffer', current_buffer ):
- assert_that(
- vimsupport.GetDiagnosticMatchPattern( 1, 16, 1, 23 ),
- equal_to( '\\%1l\\%16c\\_.\\{-}\\%1l\\%23c' )
+ result_buffer = VimBuffer(
+ single_buffer_name,
+ contents = [
+ 'line1',
+ 'line2',
+ 'line3'
+ ]
)
+ with patch( 'vim.buffers', [ None, result_buffer, None ] ):
+ vimsupport.ReplaceChunks( chunks )
-def AddDiagnosticSyntaxMatch_UnicodeAtEndOfLine_test():
- current_buffer = VimBuffer(
- 'some_file',
- contents = [ 'Highlight unicøde' ]
- )
+ # We checked if it was OK to open the file
+ confirm.assert_has_exact_calls( [
+ call( vimsupport.FIXIT_OPENING_BUFFERS_MESSAGE_FORMAT.format( 1 ) )
+ ] )
- with patch( 'vim.current.buffer', current_buffer ):
- assert_that(
- vimsupport.GetDiagnosticMatchPattern( 1, 16, 1, 19 ),
- equal_to( '\\%1l\\%16c\\_.\\{-}\\%1l\\%19c' )
- )
+ # Ensure that we applied the replacement correctly
+ assert_that( result_buffer.GetLines(), contains_exactly(
+ 'replacementline2',
+ 'line3',
+ ) )
+
+ # GetBufferNumberForFilename is called 3 times. The return values are set in
+ # the @patch call above:
+ # - once to the check if we would require opening the file (so that we can
+ # raise a warning) (-1 return)
+ # - once whilst applying the changes (-1 return)
+ # - finally after calling OpenFilename (1 return)
+ get_buffer_number_for_filename.assert_has_exact_calls( [
+ call( single_buffer_name ),
+ call( single_buffer_name ),
+ call( single_buffer_name ),
+ ] )
+ # BufferIsVisible is called 3 times for the same reasons as above, with the
+ # return of each one
+ buffer_is_visible.assert_has_exact_calls( [
+ call( -1 ),
+ call( -1 ),
+ call( 1 ),
+ ] )
-def AddDiagnosticSyntaxMatch_NonPositivePosition_test():
- current_buffer = VimBuffer(
- 'some_file',
- contents = [ 'Some contents' ]
- )
+ # We open 'single_file' as expected.
+ open_filename.assert_called_with( single_buffer_name, {
+ 'focus': True,
+ 'fix': True,
+ 'size': 10
+ } )
+
+ # And close it again, then show the quickfix window.
+ vim_command.assert_has_exact_calls( [
+ call( 'lclose' ),
+ call( 'hide' ),
+ ] )
+
+ qflist = json.dumps( [ {
+ 'bufnr': 1,
+ 'filename': single_buffer_name,
+ 'lnum': 1,
+ 'col': 1,
+ 'text': 'replacement',
+ 'type': 'F'
+ } ] )
+ # And update the quickfix list
+ vim_eval.assert_has_exact_calls( [
+ call( '&previewheight' ),
+ call( f'setqflist( { qflist } )' )
+ ] )
+
+ # And it is ReplaceChunks that prints the message showing the number of
+ # changes
+ post_vim_message.assert_has_exact_calls( [
+ call( 'Applied 1 changes', warning = False ),
+ ] )
- with patch( 'vim.current.buffer', current_buffer ):
- assert_that(
- vimsupport.GetDiagnosticMatchPattern( 0, 0, 0, 0 ),
- equal_to( '\\%1l\\%1c\\_.\\{-}\\%1l\\%1c' )
- )
- assert_that(
- vimsupport.GetDiagnosticMatchPattern( -1, -2, -3, -4 ),
- equal_to( '\\%1l\\%1c\\_.\\{-}\\%1l\\%1c' )
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ @patch( 'ycm.vimsupport.VariableExists', return_value = False )
+ @patch( 'ycm.vimsupport.SetFittingHeightForCurrentWindow' )
+ @patch( 'ycm.vimsupport.GetBufferNumberForFilename',
+ side_effect = [ -1, 1 ],
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.BufferIsVisible',
+ side_effect = [ False, True ],
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.OpenFilename',
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.Confirm',
+ return_value = True,
+ new_callable = ExtendedMock )
+ @patch( 'vim.eval', return_value = 10, new_callable = ExtendedMock )
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ def test_ReplaceChunks_SingleFile_NotOpen_Silent(
+ self,
+ vim_command,
+ vim_eval,
+ confirm,
+ post_vim_message,
+ open_filename,
+ buffer_is_visible,
+ get_buffer_number_for_filename,
+ set_fitting_height,
+ variable_exists ):
+
+ # This test is the same as ReplaceChunks_SingleFile_NotOpen_test, but we
+ # pass the silent flag, as used by post-complete actions, and shows the
+ # stuff we _don't_ call in that case.
+
+ single_buffer_name = os.path.realpath( 'single_file' )
+
+ chunks = [
+ _BuildChunk( 1, 1, 2, 1, 'replacement', single_buffer_name )
+ ]
+
+ result_buffer = VimBuffer(
+ single_buffer_name,
+ contents = [
+ 'line1',
+ 'line2',
+ 'line3'
+ ]
)
+ with patch( 'vim.buffers', [ None, result_buffer, None ] ):
+ vimsupport.ReplaceChunks( chunks, silent=True )
-@patch( 'vim.command', new_callable=ExtendedMock )
-@patch( 'vim.current', new_callable=ExtendedMock )
-def WriteToPreviewWindow_test( vim_current, vim_command ):
- vim_current.window.options.__getitem__ = MagicMock( return_value = True )
+ # We didn't check if it was OK to open the file (silent)
+ confirm.assert_not_called()
- vimsupport.WriteToPreviewWindow( "test" )
+ # Ensure that we applied the replacement correctly
+ assert_that( result_buffer.GetLines(), contains_exactly(
+ 'replacementline2',
+ 'line3',
+ ) )
+
+ # GetBufferNumberForFilename is called 2 times. The return values are set in
+ # the @patch call above:
+ # - once whilst applying the changes (-1 return)
+ # - finally after calling OpenFilename (1 return)
+ get_buffer_number_for_filename.assert_has_exact_calls( [
+ call( single_buffer_name ),
+ call( single_buffer_name ),
+ ] )
- vim_command.assert_has_exact_calls( [
- call( 'silent! pclose!' ),
- call( 'silent! pedit! _TEMP_FILE_' ),
- call( 'silent! wincmd P' ),
- call( 'silent! wincmd p' ) ] )
+ # BufferIsVisible is called 2 times for the same reasons as above, with the
+ # return of each one
+ buffer_is_visible.assert_has_exact_calls( [
+ call( -1 ),
+ call( 1 ),
+ ] )
- vim_current.buffer.__setitem__.assert_called_with(
- slice( None, None, None ), [ 'test' ] )
+ # We open 'single_file' as expected.
+ open_filename.assert_called_with( single_buffer_name, {
+ 'focus': True,
+ 'fix': True,
+ 'size': 10
+ } )
- vim_current.buffer.options.__setitem__.assert_has_exact_calls( [
- call( 'modifiable', True ),
- call( 'readonly', False ),
- call( 'buftype', 'nofile' ),
- call( 'bufhidden', 'wipe' ),
- call( 'buflisted', False ),
- call( 'swapfile', False ),
- call( 'modifiable', False ),
- call( 'modified', False ),
- call( 'readonly', True ),
- ], any_order = True )
+ # And close it again, but don't show the quickfix window
+ vim_command.assert_has_exact_calls( [
+ call( 'lclose' ),
+ call( 'hide' ),
+ ] )
+ set_fitting_height.assert_not_called()
+ # But we _don't_ update the QuickFix list
+ vim_eval.assert_has_exact_calls( [
+ call( '&previewheight' ),
+ ] )
-@patch( 'vim.current' )
-def WriteToPreviewWindow_MultiLine_test( vim_current ):
- vim_current.window.options.__getitem__ = MagicMock( return_value = True )
- vimsupport.WriteToPreviewWindow( "test\ntest2" )
+ # And we don't print a message either
+ post_vim_message.assert_not_called()
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ @patch( 'ycm.vimsupport.GetBufferNumberForFilename',
+ side_effect = [ -1, -1, 1 ],
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.BufferIsVisible',
+ side_effect = [ False, False, True ],
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.OpenFilename',
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.PostVimMessage',
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.Confirm',
+ return_value = False,
+ new_callable = ExtendedMock )
+ @patch( 'vim.eval',
+ return_value = 10,
+ new_callable = ExtendedMock )
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ def test_ReplaceChunks_User_Declines_To_Open_File(
+ self,
+ vim_command,
+ vim_eval,
+ confirm,
+ post_vim_message,
+ open_filename,
+ buffer_is_visible,
+ get_buffer_number_for_filename ):
+
+ # Same as above, except the user selects Cancel when asked if they should
+ # allow us to open lots of (ahem, 1) file.
+ single_buffer_name = os.path.realpath( 'single_file' )
+
+ chunks = [
+ _BuildChunk( 1, 1, 2, 1, 'replacement', single_buffer_name )
+ ]
- vim_current.buffer.__setitem__.assert_called_with(
- slice( None, None, None ), [ 'test', 'test2' ] )
+ result_buffer = VimBuffer(
+ single_buffer_name,
+ contents = [
+ 'line1',
+ 'line2',
+ 'line3'
+ ]
+ )
+ with patch( 'vim.buffers', [ None, result_buffer, None ] ):
+ vimsupport.ReplaceChunks( chunks )
-@patch( 'vim.command', new_callable=ExtendedMock )
-@patch( 'vim.current', new_callable=ExtendedMock )
-def WriteToPreviewWindow_JumpFail_test( vim_current, vim_command ):
- vim_current.window.options.__getitem__ = MagicMock( return_value = False )
+ # We checked if it was OK to open the file
+ confirm.assert_has_exact_calls( [
+ call( vimsupport.FIXIT_OPENING_BUFFERS_MESSAGE_FORMAT.format( 1 ) )
+ ] )
- vimsupport.WriteToPreviewWindow( "test" )
+ # Ensure that buffer is not changed
+ assert_that( result_buffer.GetLines(), contains_exactly(
+ 'line1',
+ 'line2',
+ 'line3',
+ ) )
+
+ # GetBufferNumberForFilename is called once. The return values are set in
+ # the @patch call above:
+ # - once to the check if we would require opening the file (so that we can
+ # raise a warning) (-1 return)
+ get_buffer_number_for_filename.assert_has_exact_calls( [
+ call( single_buffer_name ),
+ ] )
- vim_command.assert_has_exact_calls( [
- call( 'silent! pclose!' ),
- call( 'silent! pedit! _TEMP_FILE_' ),
- call( 'silent! wincmd P' ),
- call( 'redraw' ),
- call( "echo 'test'" ),
- ] )
+ # BufferIsVisible is called once for the above file, which wasn't visible.
+ buffer_is_visible.assert_has_exact_calls( [
+ call( -1 ),
+ ] )
- vim_current.buffer.__setitem__.assert_not_called()
- vim_current.buffer.options.__setitem__.assert_not_called()
+ # We don't attempt to open any files or update any quickfix list or anything
+ # like that
+ open_filename.assert_not_called()
+ vim_eval.assert_not_called()
+ vim_command.assert_not_called()
+ post_vim_message.assert_not_called()
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ @patch( 'ycm.vimsupport.GetBufferNumberForFilename',
+ side_effect = [ -1, -1, 1 ],
+ new_callable = ExtendedMock )
+ # Key difference is here: In the final check, BufferIsVisible returns False
+ @patch( 'ycm.vimsupport.BufferIsVisible',
+ side_effect = [ False, False, False ],
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.OpenFilename',
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.PostVimMessage',
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.Confirm',
+ return_value = True,
+ new_callable = ExtendedMock )
+ @patch( 'vim.eval',
+ return_value = 10,
+ new_callable = ExtendedMock )
+ @patch( 'vim.command',
+ new_callable = ExtendedMock )
+ def test_ReplaceChunks_User_Aborts_Opening_File(
+ self,
+ vim_command,
+ vim_eval,
+ confirm,
+ post_vim_message,
+ open_filename,
+ buffer_is_visible,
+ get_buffer_number_for_filename ):
+
+ # Same as above, except the user selects Abort or Quick during the
+ # "swap-file-found" dialog
+ single_buffer_name = os.path.realpath( 'single_file' )
+
+ chunks = [
+ _BuildChunk( 1, 1, 2, 1, 'replacement', single_buffer_name )
+ ]
+ result_buffer = VimBuffer(
+ single_buffer_name,
+ contents = [
+ 'line1',
+ 'line2',
+ 'line3'
+ ]
+ )
-@patch( 'vim.command', new_callable=ExtendedMock )
-@patch( 'vim.current', new_callable=ExtendedMock )
-def WriteToPreviewWindow_JumpFail_MultiLine_test( vim_current, vim_command ):
+ with patch( 'vim.buffers', [ None, result_buffer, None ] ):
+ assert_that(
+ calling( vimsupport.ReplaceChunks ).with_args( chunks ),
+ raises( RuntimeError,
+ 'Unable to open file: .+single_file\n'
+ 'FixIt/Refactor operation aborted prior to completion. '
+ 'Your files have not been fully updated. '
+ 'Please use undo commands to revert the applied changes.' ) )
+
+ # We checked if it was OK to open the file
+ confirm.assert_has_exact_calls( [
+ call( vimsupport.FIXIT_OPENING_BUFFERS_MESSAGE_FORMAT.format( 1 ) )
+ ] )
- vim_current.window.options.__getitem__ = MagicMock( return_value = False )
+ # Ensure that buffer is not changed
+ assert_that( result_buffer.GetLines(), contains_exactly(
+ 'line1',
+ 'line2',
+ 'line3',
+ ) )
+
+ # We tried to open this file
+ open_filename.assert_called_with( single_buffer_name, {
+ 'focus': True,
+ 'fix': True,
+ 'size': 10
+ } )
+ vim_eval.assert_called_with( "&previewheight" )
+
+ # But raised an exception before issuing the message at the end
+ post_vim_message.assert_not_called()
+
+
+ @patch( 'vim.current.window.cursor', ( 1, 1 ) )
+ @patch( 'ycm.vimsupport.VariableExists', return_value = False )
+ @patch( 'ycm.vimsupport.SetFittingHeightForCurrentWindow' )
+ @patch( 'ycm.vimsupport.GetBufferNumberForFilename', side_effect = [
+ 22, # first_file (check)
+ -1, # second_file (check)
+ 22, # first_file (apply)
+ -1, # second_file (apply)
+ 19, # second_file (check after open)
+ ],
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.BufferIsVisible', side_effect = [
+ True, # first_file (check)
+ False, # second_file (check)
+ True, # first_file (apply)
+ False, # second_file (apply)
+ True, # side_effect (check after open)
+ ],
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.OpenFilename',
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.PostVimMessage',
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.Confirm', return_value = True,
+ new_callable = ExtendedMock )
+ @patch( 'vim.eval', return_value = 10,
+ new_callable = ExtendedMock )
+ @patch( 'vim.command',
+ new_callable = ExtendedMock )
+ def test_ReplaceChunks_MultiFile_Open( self,
+ vim_command,
+ vim_eval,
+ confirm,
+ post_vim_message,
+ open_filename,
+ buffer_is_visible,
+ get_buffer_number_for_filename,
+ set_fitting_height,
+ variable_exists ):
+
+ # Chunks are split across 2 files, one is already open, one isn't
+ first_buffer_name = os.path.realpath( '1_first_file' )
+ second_buffer_name = os.path.realpath( '2_second_file' )
+
+ chunks = [
+ _BuildChunk( 1, 1, 2, 1, 'first_file_replacement ', first_buffer_name ),
+ _BuildChunk( 2, 1, 2, 1, 'second_file_replacement ', second_buffer_name ),
+ ]
- vimsupport.WriteToPreviewWindow( "test\ntest2" )
+ first_file = VimBuffer(
+ first_buffer_name,
+ number = 22,
+ contents = [
+ 'line1',
+ 'line2',
+ 'line3',
+ ]
+ )
+ second_file = VimBuffer(
+ second_buffer_name,
+ number = 19,
+ contents = [
+ 'another line1',
+ 'ACME line2',
+ ]
+ )
- vim_command.assert_has_exact_calls( [
- call( 'silent! pclose!' ),
- call( 'silent! pedit! _TEMP_FILE_' ),
- call( 'silent! wincmd P' ),
- call( 'redraw' ),
- call( "echo 'test'" ),
- call( "echo 'test2'" ),
- ] )
+ vim_buffers = [ None ] * 23
+ vim_buffers[ 22 ] = first_file
+ vim_buffers[ 19 ] = second_file
- vim_current.buffer.__setitem__.assert_not_called()
- vim_current.buffer.options.__setitem__.assert_not_called()
+ with patch( 'vim.buffers', vim_buffers ):
+ vimsupport.ReplaceChunks( chunks )
+ # We checked for the right file names
+ get_buffer_number_for_filename.assert_has_exact_calls( [
+ call( first_buffer_name ),
+ call( second_buffer_name ),
+ call( first_buffer_name ),
+ call( second_buffer_name ),
+ call( second_buffer_name ),
+ ] )
-def BufferIsVisibleForFilename_test():
- visible_buffer = VimBuffer( 'visible_filename', number = 1 )
- hidden_buffer = VimBuffer( 'hidden_filename', number = 2 )
+ # We checked if it was OK to open the file
+ confirm.assert_has_exact_calls( [
+ call( vimsupport.FIXIT_OPENING_BUFFERS_MESSAGE_FORMAT.format( 1 ) )
+ ] )
- with MockVimBuffers( [ visible_buffer, hidden_buffer ], [ visible_buffer ] ):
- assert_that( vimsupport.BufferIsVisibleForFilename( 'visible_filename' ) )
- assert_that(
- not vimsupport.BufferIsVisibleForFilename( 'hidden_filename' ) )
- assert_that(
- not vimsupport.BufferIsVisibleForFilename( 'another_filename' ) )
+ # Ensure that buffers are updated
+ assert_that( second_file.GetLines(), contains_exactly(
+ 'another line1',
+ 'second_file_replacement ACME line2',
+ ) )
+ assert_that( first_file.GetLines(), contains_exactly(
+ 'first_file_replacement line2',
+ 'line3',
+ ) )
+ # We open '2_second_file' as expected.
+ open_filename.assert_called_with( second_buffer_name, {
+ 'focus': True,
+ 'fix': True,
+ 'size': 10
+ } )
-def CloseBuffersForFilename_test():
- current_buffer = VimBuffer( 'some_filename', number = 2 )
- other_buffer = VimBuffer( 'some_filename', number = 5 )
+ # And close it again, then show the quickfix window.
+ vim_command.assert_has_exact_calls( [
+ call( 'lclose' ),
+ call( 'hide' ),
+ ] )
- with MockVimBuffers( [ current_buffer, other_buffer ],
- [ current_buffer ] ) as vim:
- vimsupport.CloseBuffersForFilename( 'some_filename' )
+ qflist = json.dumps( [ {
+ 'bufnr': 22,
+ 'filename': first_buffer_name,
+ 'lnum': 1,
+ 'col': 1,
+ 'text': 'first_file_replacement ',
+ 'type': 'F'
+ }, {
+ 'bufnr': 19,
+ 'filename': second_buffer_name,
+ 'lnum': 2,
+ 'col': 1,
+ 'text': 'second_file_replacement ',
+ 'type': 'F'
+ } ] )
+ # And update the quickfix list with each entry
+ vim_eval.assert_has_exact_calls( [
+ call( '&previewheight' ),
+ call( f'setqflist( { qflist } )' )
+ ] )
- assert_that( vim.buffers, empty() )
+ # And it is ReplaceChunks that prints the message showing the number of
+ # changes
+ post_vim_message.assert_has_exact_calls( [
+ call( 'Applied 2 changes', warning = False ),
+ ] )
-@patch( 'vim.command', new_callable = ExtendedMock )
-@patch( 'vim.current', new_callable = ExtendedMock )
-def OpenFilename_test( vim_current, vim_command ):
- # Options used to open a logfile.
- options = {
- 'size': vimsupport.GetIntValue( '&previewheight' ),
- 'fix': True,
- 'focus': False,
- 'watch': True,
- 'position': 'end'
- }
+ def test_GetDiagnosticMatchPattern_ErrorInMiddleOfLine( self ):
+ current_buffer = VimBuffer(
+ 'some_file',
+ contents = [ 'Highlight this error please' ]
+ )
- vimsupport.OpenFilename( __file__, options )
+ with patch( 'vim.current.buffer', current_buffer ):
+ assert_that(
+ vimsupport.GetDiagnosticMatchPattern( 1, 16, 1, 21 ),
+ equal_to( '\\%1l\\%16c\\_.\\{-}\\%1l\\%21c' )
+ )
- vim_command.assert_has_exact_calls( [
- call( f'12split { __file__ }' ),
- call( f"exec 'au BufEnter :silent! checktime { __file__ }'" ),
- call( 'silent! normal! Gzz' ),
- call( 'silent! wincmd p' )
- ] )
- vim_current.buffer.options.__setitem__.assert_has_exact_calls( [
- call( 'autoread', True ),
- ] )
+ def test_AddDiagnosticSyntaxMatch_WarningAtEndOfLine( self ):
+ current_buffer = VimBuffer(
+ 'some_file',
+ contents = [ 'Highlight this warning' ]
+ )
- vim_current.window.options.__setitem__.assert_has_exact_calls( [
- call( 'winfixheight', True )
- ] )
+ with patch( 'vim.current.buffer', current_buffer ):
+ assert_that(
+ vimsupport.GetDiagnosticMatchPattern( 1, 16, 1, 23 ),
+ equal_to( '\\%1l\\%16c\\_.\\{-}\\%1l\\%23c' )
+ )
-def GetUnsavedAndSpecifiedBufferData_EncodedUnicodeCharsInBuffers_test():
- filepath = os.path.realpath( 'filename' )
- contents = [ ToBytes( 'abc' ), ToBytes( 'fДa' ) ]
- vim_buffer = VimBuffer( filepath, contents = contents )
+ def test_AddDiagnosticSyntaxMatch_UnicodeAtEndOfLine( self ):
+ current_buffer = VimBuffer(
+ 'some_file',
+ contents = [ 'Highlight unicøde' ]
+ )
- with patch( 'vim.buffers', [ vim_buffer ] ):
- assert_that( vimsupport.GetUnsavedAndSpecifiedBufferData( vim_buffer,
- filepath ),
- has_entry( filepath,
- has_entry( 'contents', 'abc\nfДa\n' ) ) )
+ with patch( 'vim.current.buffer', current_buffer ):
+ assert_that(
+ vimsupport.GetDiagnosticMatchPattern( 1, 16, 1, 19 ),
+ equal_to( '\\%1l\\%16c\\_.\\{-}\\%1l\\%19c' )
+ )
-def GetBufferFilepath_NoBufferName_UnicodeWorkingDirectory_test():
- vim_buffer = VimBuffer( '', number = 42 )
- unicode_dir = PathToTestFile( 'uni¢od€' )
- with CurrentWorkingDirectory( unicode_dir ):
- assert_that( vimsupport.GetBufferFilepath( vim_buffer ),
- equal_to( os.path.join( unicode_dir, '42' ) ) )
+ def test_AddDiagnosticSyntaxMatch_NonPositivePosition( self ):
+ current_buffer = VimBuffer(
+ 'some_file',
+ contents = [ 'Some contents' ]
+ )
+ with patch( 'vim.current.buffer', current_buffer ):
+ assert_that(
+ vimsupport.GetDiagnosticMatchPattern( 0, 0, 0, 0 ),
+ equal_to( '\\%1l\\%1c\\_.\\{-}\\%1l\\%1c' )
+ )
-# NOTE: Vim returns byte offsets for columns, not actual character columns. This
-# makes 'ДД' have 4 columns: column 0, column 2 and column 4.
-@patch( 'vim.current.line', ToBytes( 'ДДaa' ) )
-@patch( 'ycm.vimsupport.CurrentColumn', side_effect = [ 4 ] )
-def TextBeforeCursor_EncodedUnicode_test( *args ):
- assert_that( vimsupport.TextBeforeCursor(), equal_to( 'ДД' ) )
+ assert_that(
+ vimsupport.GetDiagnosticMatchPattern( -1, -2, -3, -4 ),
+ equal_to( '\\%1l\\%1c\\_.\\{-}\\%1l\\%1c' )
+ )
-# NOTE: Vim returns byte offsets for columns, not actual character columns. This
-# makes 'ДД' have 4 columns: column 0, column 2 and column 4.
-@patch( 'vim.current.line', ToBytes( 'aaДД' ) )
-@patch( 'ycm.vimsupport.CurrentColumn', side_effect = [ 2 ] )
-def TextAfterCursor_EncodedUnicode_test( *args ):
- assert_that( vimsupport.TextAfterCursor(), equal_to( 'ДД' ) )
+ @patch( 'vim.command', new_callable=ExtendedMock )
+ @patch( 'vim.current', new_callable=ExtendedMock )
+ def test_WriteToPreviewWindow( self, vim_current, vim_command ):
+ vim_current.window.options.__getitem__ = MagicMock( return_value = True )
+ vimsupport.WriteToPreviewWindow( "test" )
-@patch( 'vim.current.line', ToBytes( 'fДa' ) )
-def CurrentLineContents_EncodedUnicode_test( *args ):
- assert_that( vimsupport.CurrentLineContents(), equal_to( 'fДa' ) )
+ vim_command.assert_has_exact_calls( [
+ call( 'silent! pclose!' ),
+ call( 'silent! pedit! _TEMP_FILE_' ),
+ call( 'silent! wincmd P' ),
+ call( 'silent! wincmd p' ) ] )
+ vim_current.buffer.__setitem__.assert_called_with(
+ slice( None, None, None ), [ 'test' ] )
-@patch( 'vim.eval', side_effect = lambda x: x )
-def VimExpressionToPythonType_IntAsUnicode_test( *args ):
- assert_that( vimsupport.VimExpressionToPythonType( '123' ), equal_to( 123 ) )
+ vim_current.buffer.options.__setitem__.assert_has_exact_calls( [
+ call( 'modifiable', True ),
+ call( 'readonly', False ),
+ call( 'buftype', 'nofile' ),
+ call( 'bufhidden', 'wipe' ),
+ call( 'buflisted', False ),
+ call( 'swapfile', False ),
+ call( 'modifiable', False ),
+ call( 'modified', False ),
+ call( 'readonly', True ),
+ ], any_order = True )
-@patch( 'vim.eval', side_effect = lambda x: x )
-def VimExpressionToPythonType_IntAsBytes_test( *args ):
- assert_that( vimsupport.VimExpressionToPythonType( ToBytes( '123' ) ),
- equal_to( 123 ) )
+ @patch( 'vim.current' )
+ def test_WriteToPreviewWindow_MultiLine( self, vim_current ):
+ vim_current.window.options.__getitem__ = MagicMock( return_value = True )
+ vimsupport.WriteToPreviewWindow( "test\ntest2" )
+ vim_current.buffer.__setitem__.assert_called_with(
+ slice( None, None, None ), [ 'test', 'test2' ] )
-@patch( 'vim.eval', side_effect = lambda x: x )
-def VimExpressionToPythonType_StringAsUnicode_test( *args ):
- assert_that( vimsupport.VimExpressionToPythonType( 'foo' ),
- equal_to( 'foo' ) )
+ @patch( 'vim.command', new_callable=ExtendedMock )
+ @patch( 'vim.current', new_callable=ExtendedMock )
+ def test_WriteToPreviewWindow_JumpFail( self, vim_current, vim_command ):
+ vim_current.window.options.__getitem__ = MagicMock( return_value = False )
-@patch( 'vim.eval', side_effect = lambda x: x )
-def VimExpressionToPythonType_StringAsBytes_test( *args ):
- assert_that( vimsupport.VimExpressionToPythonType( ToBytes( 'foo' ) ),
- equal_to( 'foo' ) )
+ vimsupport.WriteToPreviewWindow( "test" )
+ vim_command.assert_has_exact_calls( [
+ call( 'silent! pclose!' ),
+ call( 'silent! pedit! _TEMP_FILE_' ),
+ call( 'silent! wincmd P' ),
+ call( 'redraw' ),
+ call( "echo 'test'" ),
+ ] )
-@patch( 'vim.eval', side_effect = lambda x: x )
-def VimExpressionToPythonType_ListPassthrough_test( *args ):
- assert_that( vimsupport.VimExpressionToPythonType( [ 1, 2 ] ),
- equal_to( [ 1, 2 ] ) )
+ vim_current.buffer.__setitem__.assert_not_called()
+ vim_current.buffer.options.__setitem__.assert_not_called()
-@patch( 'vim.eval', side_effect = lambda x: x )
-def VimExpressionToPythonType_ObjectPassthrough_test( *args ):
- assert_that( vimsupport.VimExpressionToPythonType( { 1: 2 } ),
- equal_to( { 1: 2 } ) )
+ @patch( 'vim.command', new_callable=ExtendedMock )
+ @patch( 'vim.current', new_callable=ExtendedMock )
+ def test_WriteToPreviewWindow_JumpFail_MultiLine(
+ self, vim_current, vim_command ):
+ vim_current.window.options.__getitem__ = MagicMock( return_value = False )
-@patch( 'vim.eval', side_effect = lambda x: x )
-def VimExpressionToPythonType_GeneratorPassthrough_test( *args ):
- gen = ( x**2 for x in [ 1, 2, 3 ] )
- assert_that( vimsupport.VimExpressionToPythonType( gen ), equal_to( gen ) )
+ vimsupport.WriteToPreviewWindow( "test\ntest2" )
+ vim_command.assert_has_exact_calls( [
+ call( 'silent! pclose!' ),
+ call( 'silent! pedit! _TEMP_FILE_' ),
+ call( 'silent! wincmd P' ),
+ call( 'redraw' ),
+ call( "echo 'test'" ),
+ call( "echo 'test2'" ),
+ ] )
-@patch( 'vim.eval',
- new_callable = ExtendedMock,
- side_effect = [ None, 2, None ] )
-def SelectFromList_LastItem_test( vim_eval ):
- assert_that( vimsupport.SelectFromList( 'test', [ 'a', 'b' ] ),
- equal_to( 1 ) )
+ vim_current.buffer.__setitem__.assert_not_called()
+ vim_current.buffer.options.__setitem__.assert_not_called()
- vim_eval.assert_has_exact_calls( [
- call( 'inputsave()' ),
- call( 'inputlist( ["test", "1: a", "2: b"] )' ),
- call( 'inputrestore()' )
- ] )
+ def test_BufferIsVisibleForFilename( self ):
+ visible_buffer = VimBuffer( 'visible_filename', number = 1 )
+ hidden_buffer = VimBuffer( 'hidden_filename', number = 2 )
-@patch( 'vim.eval',
- new_callable = ExtendedMock,
- side_effect = [ None, 1, None ] )
-def SelectFromList_FirstItem_test( vim_eval ):
- assert_that( vimsupport.SelectFromList( 'test', [ 'a', 'b' ] ),
- equal_to( 0 ) )
+ with MockVimBuffers( [ visible_buffer, hidden_buffer ],
+ [ visible_buffer ] ):
+ assert_that( vimsupport.BufferIsVisibleForFilename( 'visible_filename' ) )
+ assert_that(
+ not vimsupport.BufferIsVisibleForFilename( 'hidden_filename' ) )
+ assert_that(
+ not vimsupport.BufferIsVisibleForFilename( 'another_filename' ) )
- vim_eval.assert_has_exact_calls( [
- call( 'inputsave()' ),
- call( 'inputlist( ["test", "1: a", "2: b"] )' ),
- call( 'inputrestore()' )
- ] )
+ def test_CloseBuffersForFilename( self ):
+ current_buffer = VimBuffer( 'some_filename', number = 2 )
+ other_buffer = VimBuffer( 'some_filename', number = 5 )
-@patch( 'vim.eval', side_effect = [ None, 3, None ] )
-def SelectFromList_OutOfRange_test( vim_eval ):
- assert_that( calling( vimsupport.SelectFromList ).with_args( 'test',
- [ 'a', 'b' ] ),
- raises( RuntimeError, vimsupport.NO_SELECTION_MADE_MSG ) )
+ with MockVimBuffers( [ current_buffer, other_buffer ],
+ [ current_buffer ] ) as vim:
+ vimsupport.CloseBuffersForFilename( 'some_filename' )
+ assert_that( vim.buffers, empty() )
-@patch( 'vim.eval', side_effect = [ None, 0, None ] )
-def SelectFromList_SelectPrompt_test( vim_eval ):
- assert_that( calling( vimsupport.SelectFromList ).with_args( 'test',
- [ 'a', 'b' ] ),
- raises( RuntimeError, vimsupport.NO_SELECTION_MADE_MSG ) )
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ @patch( 'vim.current', new_callable = ExtendedMock )
+ def test_OpenFilename( self, vim_current, vim_command ):
+ # Options used to open a logfile.
+ options = {
+ 'size': vimsupport.GetIntValue( '&previewheight' ),
+ 'fix': True,
+ 'focus': False,
+ 'watch': True,
+ 'position': 'end'
+ }
+
+ vimsupport.OpenFilename( __file__, options )
-@patch( 'vim.eval', side_effect = [ None, -199, None ] )
-def SelectFromList_Negative_test( vim_eval ):
- assert_that( calling( vimsupport.SelectFromList ).with_args( 'test',
- [ 'a', 'b' ] ),
- raises( RuntimeError, vimsupport.NO_SELECTION_MADE_MSG ) )
-
-
-def Filetypes_IntegerFiletype_test():
- current_buffer = VimBuffer( 'buffer', number = 1, filetype = '42' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- assert_that( vimsupport.CurrentFiletypes(), contains_exactly( '42' ) )
- assert_that( vimsupport.GetBufferFiletypes( 1 ), contains_exactly( '42' ) )
- assert_that( vimsupport.FiletypesForBuffer( current_buffer ),
- contains_exactly( '42' ) )
-
-
-@patch( 'ycm.vimsupport.VariableExists', return_value = False )
-@patch( 'ycm.vimsupport.SearchInCurrentBuffer', return_value = 0 )
-@patch( 'vim.current' )
-def InsertNamespace_insert_test( vim_current, *args ):
- contents = [ '',
- 'namespace Taqueria {',
- '',
- ' int taco = Math' ]
- vim_current.buffer = VimBuffer( '', contents = contents )
- vim_current.window.cursor = ( 1, 1 )
-
- vimsupport.InsertNamespace( 'System' )
-
- expected_buffer = [ 'using System;',
- '',
- 'namespace Taqueria {',
- '',
- ' int taco = Math' ]
- AssertBuffersAreEqualAsBytes( expected_buffer, vim_current.buffer )
-
-
-@patch( 'ycm.vimsupport.VariableExists', return_value = False )
-@patch( 'ycm.vimsupport.SearchInCurrentBuffer', return_value = 2 )
-@patch( 'vim.current' )
-def InsertNamespace_append_test( vim_current, *args ):
- contents = [ 'namespace Taqueria {',
- ' using System;',
- '',
- ' class Tasty {',
- ' int taco;',
- ' List salad = new List' ]
- vim_current.buffer = VimBuffer( '', contents = contents )
- vim_current.window.cursor = ( 1, 1 )
-
- vimsupport.InsertNamespace( 'System.Collections' )
-
- expected_buffer = [ 'namespace Taqueria {',
- ' using System;',
- ' using System.Collections;',
- '',
- ' class Tasty {',
- ' int taco;',
- ' List salad = new List' ]
- AssertBuffersAreEqualAsBytes( expected_buffer, vim_current.buffer )
-
-
-@patch( 'vim.command', new_callable = ExtendedMock )
-def JumpToLocation_SameFile_SameBuffer_NoSwapFile_test( vim_command ):
- current_buffer = VimBuffer( 'uni¢𐍈d€' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
- vimsupport.JumpToLocation( os.path.realpath( 'uni¢𐍈d€' ),
- 2,
- 5,
- 'aboveleft',
- 'same-buffer' )
-
- assert_that( vim.current.window.cursor, equal_to( ( 2, 4 ) ) )
vim_command.assert_has_exact_calls( [
- call( 'normal! m\'' ),
- call( 'normal! zz' )
+ call( f'12split { __file__ }' ),
+ call( f"exec 'au BufEnter :silent! checktime { __file__ }'" ),
+ call( 'silent! normal! Gzz' ),
+ call( 'silent! wincmd p' )
] )
+ vim_current.buffer.options.__setitem__.assert_has_exact_calls( [
+ call( 'autoread', True ),
+ ] )
-@patch( 'vim.command', new_callable = ExtendedMock )
-def JumpToLocation_DifferentFile_SameBuffer_Unmodified_test( vim_command ):
- current_buffer = VimBuffer( 'uni¢𐍈d€' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
- target_name = os.path.realpath( 'different_uni¢𐍈d€' )
+ vim_current.window.options.__setitem__.assert_has_exact_calls( [
+ call( 'winfixheight', True )
+ ] )
- vimsupport.JumpToLocation( target_name, 2, 5, 'belowright', 'same-buffer' )
- assert_that( vim.current.window.cursor, equal_to( ( 2, 4 ) ) )
- vim_command.assert_has_exact_calls( [
- call( 'normal! m\'' ),
- call( f'keepjumps belowright edit { target_name }' ),
- call( 'normal! zz' )
- ] )
+ def test_GetUnsavedAndSpecifiedBufferData_EncodedUnicodeCharsInBuffers(
+ self ):
+ filepath = os.path.realpath( 'filename' )
+ contents = [ ToBytes( 'abc' ), ToBytes( 'fДa' ) ]
+ vim_buffer = VimBuffer( filepath, contents = contents )
+ with patch( 'vim.buffers', [ vim_buffer ] ):
+ assert_that( vimsupport.GetUnsavedAndSpecifiedBufferData( vim_buffer,
+ filepath ),
+ has_entry( filepath,
+ has_entry( 'contents', 'abc\nfДa\n' ) ) )
-@patch( 'vim.command', new_callable = ExtendedMock )
-def JumpToLocation_DifferentFile_SameBuffer_Modified_CannotHide_test(
- vim_command ):
- current_buffer = VimBuffer( 'uni¢𐍈d€', modified = True )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
- target_name = os.path.realpath( 'different_uni¢𐍈d€' )
+ def test_GetBufferFilepath_NoBufferName_UnicodeWorkingDirectory( self ):
+ vim_buffer = VimBuffer( '', number = 42 )
+ unicode_dir = PathToTestFile( 'uni¢od€' )
+ with CurrentWorkingDirectory( unicode_dir ):
+ assert_that( vimsupport.GetBufferFilepath( vim_buffer ),
+ equal_to( os.path.join( unicode_dir, '42' ) ) )
- vimsupport.JumpToLocation( target_name, 2, 5, 'botright', 'same-buffer' )
- assert_that( vim.current.window.cursor, equal_to( ( 2, 4 ) ) )
- vim_command.assert_has_exact_calls( [
- call( 'normal! m\'' ),
- call( f'keepjumps botright split { target_name }' ),
- call( 'normal! zz' )
- ] )
+ # NOTE: Vim returns byte offsets for columns, not actual character columns.
+ # This makes 'ДД' have 4 columns: column 0, column 2 and column 4.
+ @patch( 'vim.current.line', ToBytes( 'ДДaa' ) )
+ @patch( 'ycm.vimsupport.CurrentColumn', side_effect = [ 4 ] )
+ def test_TextBeforeCursor_EncodedUnicode( *args ):
+ assert_that( vimsupport.TextBeforeCursor(), equal_to( 'ДД' ) )
-@patch( 'vim.command', new_callable = ExtendedMock )
-def JumpToLocation_DifferentFile_SameBuffer_Modified_CanHide_test(
- vim_command ):
+ # NOTE: Vim returns byte offsets for columns, not actual character columns.
+ # This makes 'ДД' have 4 columns: column 0, column 2 and column 4.
+ @patch( 'vim.current.line', ToBytes( 'aaДД' ) )
+ @patch( 'ycm.vimsupport.CurrentColumn', side_effect = [ 2 ] )
+ def test_TextAfterCursor_EncodedUnicode( *args ):
+ assert_that( vimsupport.TextAfterCursor(), equal_to( 'ДД' ) )
- current_buffer = VimBuffer( 'uni¢𐍈d€', modified = True, bufhidden = "hide" )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
- target_name = os.path.realpath( 'different_uni¢𐍈d€' )
- vimsupport.JumpToLocation( target_name, 2, 5, 'leftabove', 'same-buffer' )
+ @patch( 'vim.current.line', ToBytes( 'fДa' ) )
+ def test_CurrentLineContents_EncodedUnicode( *args ):
+ assert_that( vimsupport.CurrentLineContents(), equal_to( 'fДa' ) )
- assert_that( vim.current.window.cursor, equal_to( ( 2, 4 ) ) )
- vim_command.assert_has_exact_calls( [
- call( 'normal! m\'' ),
- call( f'keepjumps leftabove edit { target_name }' ),
- call( 'normal! zz' )
- ] )
+ @patch( 'vim.eval', side_effect = lambda x: x )
+ def test_VimExpressionToPythonType_IntAsUnicode( *args ):
+ assert_that( vimsupport.VimExpressionToPythonType( '123' ),
+ equal_to( 123 ) )
-@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( 'different_uni¢𐍈d€' ),
- 2,
- 5,
- 'rightbelow',
- 'same-buffer' ),
- raises( VimError, 'Unknown code' )
- )
+ @patch( 'vim.eval', side_effect = lambda x: x )
+ def test_VimExpressionToPythonType_IntAsBytes( *args ):
+ assert_that( vimsupport.VimExpressionToPythonType( ToBytes( '123' ) ),
+ equal_to( 123 ) )
-@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( 'different_uni¢𐍈d€' )
- vimsupport.JumpToLocation( target_name, 2, 5, 'topleft', 'same-buffer' )
+ @patch( 'vim.eval', side_effect = lambda x: x )
+ def test_VimExpressionToPythonType_StringAsUnicode( *args ):
+ assert_that( vimsupport.VimExpressionToPythonType( 'foo' ),
+ equal_to( 'foo' ) )
- vim_command.assert_has_exact_calls( [
- call( 'normal! m\'' ),
- call( f'keepjumps topleft edit { target_name }' )
- ] )
+ @patch( 'vim.eval', side_effect = lambda x: x )
+ def test_VimExpressionToPythonType_StringAsBytes( *args ):
+ assert_that( vimsupport.VimExpressionToPythonType( ToBytes( 'foo' ) ),
+ equal_to( 'foo' ) )
-@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( 'different_uni¢𐍈d€' )
- vimsupport.JumpToLocation( target_name, 2, 5, 'vertical', 'same-buffer' )
+ @patch( 'vim.eval', side_effect = lambda x: x )
+ def test_VimExpressionToPythonType_ListPassthrough( *args ):
+ assert_that( vimsupport.VimExpressionToPythonType( [ 1, 2 ] ),
+ equal_to( [ 1, 2 ] ) )
- vim_command.assert_has_exact_calls( [
- call( 'normal! m\'' ),
- call( f'keepjumps vertical edit { target_name }' )
- ] )
+ @patch( 'vim.eval', side_effect = lambda x: x )
+ def test_VimExpressionToPythonType_ObjectPassthrough( *args ):
+ assert_that( vimsupport.VimExpressionToPythonType( { 1: 2 } ),
+ equal_to( { 1: 2 } ) )
-@patch( 'vim.command', new_callable = ExtendedMock )
-def JumpToLocation_DifferentFile_Split_CurrentTab_NotAlreadyOpened_test(
- vim_command ):
- current_buffer = VimBuffer( 'uni¢𐍈d€' )
- current_window = MagicMock( buffer = current_buffer )
- current_tab = MagicMock( windows = [ current_window ] )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
- vim.current.tabpage = current_tab
+ @patch( 'vim.eval', side_effect = lambda x: x )
+ def test_VimExpressionToPythonType_GeneratorPassthrough( *args ):
+ gen = ( x**2 for x in [ 1, 2, 3 ] )
+ assert_that( vimsupport.VimExpressionToPythonType( gen ), equal_to( gen ) )
- target_name = os.path.realpath( 'different_uni¢𐍈d€' )
- vimsupport.JumpToLocation( target_name,
- 2,
- 5,
- 'aboveleft',
- 'split-or-existing-window' )
+ @patch( 'vim.eval',
+ new_callable = ExtendedMock,
+ side_effect = [ None, 2, None ] )
+ def test_SelectFromList_LastItem( self, vim_eval ):
+ assert_that( vimsupport.SelectFromList( 'test', [ 'a', 'b' ] ),
+ equal_to( 1 ) )
- vim_command.assert_has_exact_calls( [
- call( 'normal! m\'' ),
- call( f'keepjumps aboveleft split { target_name }' ),
- call( 'normal! zz' )
+ vim_eval.assert_has_exact_calls( [
+ call( 'inputsave()' ),
+ call( 'inputlist( ["test", "1: a", "2: b"] )' ),
+ call( 'inputrestore()' )
] )
-@patch( 'vim.command', new_callable = ExtendedMock )
-def JumpToLocation_DifferentFile_Split_CurrentTab_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 MockVimBuffers( [ current_buffer, different_buffer ],
- [ current_buffer ] ) as vim:
- vim.current.tabpage = current_tab
-
- vimsupport.JumpToLocation( os.path.realpath( 'different_uni¢𐍈d€' ),
- 2,
- 5,
- 'belowright',
- 'split-or-existing-window' )
-
- 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' )
+ @patch( 'vim.eval',
+ new_callable = ExtendedMock,
+ side_effect = [ None, 1, None ] )
+ def test_SelectFromList_FirstItem( self, vim_eval ):
+ assert_that( vimsupport.SelectFromList( 'test', [ 'a', 'b' ] ),
+ equal_to( 0 ) )
+
+ vim_eval.assert_has_exact_calls( [
+ call( 'inputsave()' ),
+ call( 'inputlist( ["test", "1: a", "2: b"] )' ),
+ call( 'inputrestore()' )
] )
-@WindowsAndMacOnly
-@patch( 'vim.command', new_callable = ExtendedMock )
-def JumpToLocation_DifferentFile_Split_CurrentTab_AlreadyOpened_Case_test(
- vim_command ):
-
- current_buffer = VimBuffer( 'current_buffer' )
- different_buffer = VimBuffer( 'AnotHer_buFfeR' )
- current_window = MagicMock( buffer = current_buffer )
- different_window = MagicMock( buffer = different_buffer )
- current_tab = MagicMock( windows = [ current_window, different_window ] )
- with MockVimBuffers( [ current_buffer, different_buffer ],
- [ current_buffer ] ) as vim:
- vim.current.tabpage = current_tab
-
- vimsupport.JumpToLocation( os.path.realpath( 'anOther_BuffEr' ),
- 4,
- 1,
- 'belowright',
- 'split-or-existing-window' )
-
- 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( ( 4, 0 ) ) )
- vim_command.assert_has_exact_calls( [
- call( 'normal! m\'' ),
- call( 'normal! zz' )
- ] )
+ @patch( 'vim.eval', side_effect = [ None, 3, None ] )
+ def test_SelectFromList_OutOfRange( self, vim_eval ):
+ assert_that( calling( vimsupport.SelectFromList ).with_args( 'test',
+ [ 'a', 'b' ] ),
+ raises( RuntimeError, vimsupport.NO_SELECTION_MADE_MSG ) )
-@patch( 'vim.command', new_callable = ExtendedMock )
-def JumpToLocation_DifferentFile_Split_AllTabs_NotAlreadyOpened_test(
- vim_command ):
+ @patch( 'vim.eval', side_effect = [ None, 0, None ] )
+ def test_SelectFromList_SelectPrompt( self, vim_eval ):
+ assert_that( calling( vimsupport.SelectFromList ).with_args( 'test',
+ [ 'a', 'b' ] ),
+ raises( RuntimeError, vimsupport.NO_SELECTION_MADE_MSG ) )
+
+
+ @patch( 'vim.eval', side_effect = [ None, -199, None ] )
+ def test_SelectFromList_Negative( self, vim_eval ):
+ assert_that( calling( vimsupport.SelectFromList ).with_args( 'test',
+ [ 'a', 'b' ] ),
+ raises( RuntimeError, vimsupport.NO_SELECTION_MADE_MSG ) )
+
+
+ def test_Filetypes_IntegerFiletype( self ):
+ current_buffer = VimBuffer( 'buffer', number = 1, filetype = '42' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ assert_that( vimsupport.CurrentFiletypes(), contains_exactly( '42' ) )
+ assert_that( vimsupport.GetBufferFiletypes( 1 ),
+ contains_exactly( '42' ) )
+ assert_that( vimsupport.FiletypesForBuffer( current_buffer ),
+ contains_exactly( '42' ) )
+
+
+ @patch( 'ycm.vimsupport.VariableExists', return_value = False )
+ @patch( 'ycm.vimsupport.SearchInCurrentBuffer', return_value = 0 )
+ @patch( 'vim.current' )
+ def test_InsertNamespace_insert( self, vim_current, *args ):
+ contents = [ '',
+ 'namespace Taqueria {',
+ '',
+ ' int taco = Math' ]
+ vim_current.buffer = VimBuffer( '', contents = contents )
+ vim_current.window.cursor = ( 1, 1 )
+
+ vimsupport.InsertNamespace( 'System' )
+
+ expected_buffer = [ 'using System;',
+ '',
+ 'namespace Taqueria {',
+ '',
+ ' int taco = Math' ]
+ AssertBuffersAreEqualAsBytes( expected_buffer, vim_current.buffer )
+
+
+ @patch( 'ycm.vimsupport.VariableExists', return_value = False )
+ @patch( 'ycm.vimsupport.SearchInCurrentBuffer', return_value = 2 )
+ @patch( 'vim.current' )
+ def test_InsertNamespace_append( self, vim_current, *args ):
+ contents = [ 'namespace Taqueria {',
+ ' using System;',
+ '',
+ ' class Tasty {',
+ ' int taco;',
+ ' List salad = new List' ]
+ vim_current.buffer = VimBuffer( '', contents = contents )
+ vim_current.window.cursor = ( 1, 1 )
+
+ vimsupport.InsertNamespace( 'System.Collections' )
+
+ expected_buffer = [ 'namespace Taqueria {',
+ ' using System;',
+ ' using System.Collections;',
+ '',
+ ' class Tasty {',
+ ' int taco;',
+ ' List salad = new List' ]
+ AssertBuffersAreEqualAsBytes( expected_buffer, vim_current.buffer )
+
+
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ def test_JumpToLocation_SameFile_SameBuffer_NoSwapFile( self, vim_command ):
+ current_buffer = VimBuffer( 'uni¢𐍈d€' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
+ vimsupport.JumpToLocation( os.path.realpath( 'uni¢𐍈d€' ),
+ 2,
+ 5,
+ 'aboveleft',
+ 'same-buffer' )
- current_buffer = VimBuffer( 'uni¢𐍈d€' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- target_name = os.path.realpath( 'different_uni¢𐍈d€' )
+ assert_that( vim.current.window.cursor, equal_to( ( 2, 4 ) ) )
+ vim_command.assert_has_exact_calls( [
+ call( 'normal! m\'' ),
+ call( 'normal! zz' )
+ ] )
- vimsupport.JumpToLocation( target_name,
- 2,
- 5,
- 'tab',
- 'split-or-existing-window' )
- vim_command.assert_has_exact_calls( [
- call( 'normal! m\'' ),
- call( f'keepjumps tab split { target_name }' ),
- call( 'normal! zz' )
- ] )
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ def test_JumpToLocation_DifferentFile_SameBuffer_Unmodified(
+ self, vim_command ):
+ current_buffer = VimBuffer( 'uni¢𐍈d€' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
+ target_name = os.path.realpath( 'different_uni¢𐍈d€' )
+
+ vimsupport.JumpToLocation( target_name,
+ 2,
+ 5,
+ 'belowright',
+ 'same-buffer' )
+
+ assert_that( vim.current.window.cursor, equal_to( ( 2, 4 ) ) )
+ vim_command.assert_has_exact_calls( [
+ call( 'normal! m\'' ),
+ call( f'keepjumps belowright edit { target_name }' ),
+ call( 'normal! zz' )
+ ] )
+
+
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ def test_JumpToLocation_DifferentFile_SameBuffer_Modified_CannotHide(
+ self, vim_command ):
+
+ current_buffer = VimBuffer( 'uni¢𐍈d€', modified = True )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
+ target_name = os.path.realpath( 'different_uni¢𐍈d€' )
+
+ vimsupport.JumpToLocation( target_name, 2, 5, 'botright', 'same-buffer' )
+
+ assert_that( vim.current.window.cursor, equal_to( ( 2, 4 ) ) )
+ vim_command.assert_has_exact_calls( [
+ call( 'normal! m\'' ),
+ call( f'keepjumps botright split { target_name }' ),
+ call( 'normal! zz' )
+ ] )
+
+
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ def test_JumpToLocation_DifferentFile_SameBuffer_Modified_CanHide(
+ self, vim_command ):
+
+ current_buffer = VimBuffer( 'uni¢𐍈d€', modified = True, bufhidden = "hide" )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
+ target_name = os.path.realpath( 'different_uni¢𐍈d€' )
+
+ vimsupport.JumpToLocation( target_name, 2, 5, 'leftabove', 'same-buffer' )
+
+ assert_that( vim.current.window.cursor, equal_to( ( 2, 4 ) ) )
+ vim_command.assert_has_exact_calls( [
+ call( 'normal! m\'' ),
+ call( f'keepjumps leftabove edit { target_name }' ),
+ call( 'normal! zz' )
+ ] )
+
+
+ @patch( 'vim.command',
+ side_effect = [ None, VimError( 'Unknown code' ), None ] )
+ def test_JumpToLocation_DifferentFile_SameBuffer_SwapFile_Unexpected(
+ self, vim_command ):
+
+ current_buffer = VimBuffer( 'uni¢𐍈d€' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ assert_that(
+ calling( vimsupport.JumpToLocation ).with_args(
+ os.path.realpath( 'different_uni¢𐍈d€' ),
+ 2,
+ 5,
+ 'rightbelow',
+ 'same-buffer' ),
+ raises( VimError, 'Unknown code' )
+ )
+
+
+ @patch( 'vim.command',
+ new_callable = ExtendedMock,
+ side_effect = [ None, VimError( 'E325' ), None ] )
+ def test_JumpToLocation_DifferentFile_SameBuffer_SwapFile_Quit(
+ self, vim_command ):
+ current_buffer = VimBuffer( 'uni¢𐍈d€' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ target_name = os.path.realpath( 'different_uni¢𐍈d€' )
+
+ vimsupport.JumpToLocation( target_name, 2, 5, 'topleft', 'same-buffer' )
+
+ vim_command.assert_has_exact_calls( [
+ call( 'normal! m\'' ),
+ call( f'keepjumps topleft edit { target_name }' )
+ ] )
+
+
+ @patch( 'vim.command',
+ new_callable = ExtendedMock,
+ side_effect = [ None, KeyboardInterrupt, None ] )
+ def test_JumpToLocation_DifferentFile_SameBuffer_SwapFile_Abort(
+ self, vim_command ):
+ current_buffer = VimBuffer( 'uni¢𐍈d€' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ target_name = os.path.realpath( 'different_uni¢𐍈d€' )
+
+ vimsupport.JumpToLocation( target_name, 2, 5, 'vertical', 'same-buffer' )
+
+ vim_command.assert_has_exact_calls( [
+ call( 'normal! m\'' ),
+ call( f'keepjumps vertical edit { target_name }' )
+ ] )
+
+
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ def test_JumpToLocation_DifferentFile_Split_CurrentTab_NotAlreadyOpened(
+ self, vim_command ):
+
+ current_buffer = VimBuffer( 'uni¢𐍈d€' )
+ current_window = MagicMock( buffer = current_buffer )
+ current_tab = MagicMock( windows = [ current_window ] )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ) as vim:
+ vim.current.tabpage = current_tab
+
+ target_name = os.path.realpath( 'different_uni¢𐍈d€' )
+
+ vimsupport.JumpToLocation( target_name,
+ 2,
+ 5,
+ 'aboveleft',
+ 'split-or-existing-window' )
+
+ vim_command.assert_has_exact_calls( [
+ call( 'normal! m\'' ),
+ call( f'keepjumps aboveleft split { target_name }' ),
+ call( 'normal! zz' )
+ ] )
-@patch( 'vim.command', new_callable = ExtendedMock )
-def JumpToLocation_DifferentFile_Split_AllTabs_AlreadyOpened_test(
- vim_command ):
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ def test_JumpToLocation_DifferentFile_Split_CurrentTab_AlreadyOpened(
+ self, 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 ] ):
+ 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 MockVimBuffers( [ current_buffer, different_buffer ],
[ current_buffer ] ) as vim:
+ vim.current.tabpage = current_tab
+
vimsupport.JumpToLocation( os.path.realpath( 'different_uni¢𐍈d€' ),
2,
5,
- 'tab',
+ 'belowright',
'split-or-existing-window' )
assert_that( vim.current.tabpage, equal_to( current_tab ) )
@@ -1963,58 +1913,135 @@ def JumpToLocation_DifferentFile_Split_AllTabs_AlreadyOpened_test(
] )
-@patch( 'vim.command', new_callable = ExtendedMock )
-def JumpToLocation_DifferentFile_NewOrExistingTab_NotAlreadyOpened_test(
- vim_command ):
+ @WindowsAndMacOnly
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ def test_JumpToLocation_DifferentFile_Split_CurrentTab_AlreadyOpened_Case(
+ self, vim_command ):
- current_buffer = VimBuffer( 'uni¢𐍈d€' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- target_name = os.path.realpath( 'different_uni¢𐍈d€' )
+ current_buffer = VimBuffer( 'current_buffer' )
+ different_buffer = VimBuffer( 'AnotHer_buFfeR' )
+ current_window = MagicMock( buffer = current_buffer )
+ different_window = MagicMock( buffer = different_buffer )
+ current_tab = MagicMock( windows = [ current_window, different_window ] )
+ with MockVimBuffers( [ current_buffer, different_buffer ],
+ [ current_buffer ] ) as vim:
+ vim.current.tabpage = current_tab
- vimsupport.JumpToLocation( target_name,
- 2,
- 5,
- 'aboveleft vertical',
- 'new-or-existing-tab' )
+ vimsupport.JumpToLocation( os.path.realpath( 'anOther_BuffEr' ),
+ 4,
+ 1,
+ 'belowright',
+ 'split-or-existing-window' )
- vim_command.assert_has_exact_calls( [
- call( 'normal! m\'' ),
- call( f'keepjumps aboveleft vertical tabedit { target_name }' ),
- call( 'normal! zz' )
- ] )
+ 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( ( 4, 0 ) ) )
+ vim_command.assert_has_exact_calls( [
+ call( 'normal! m\'' ),
+ call( 'normal! zz' )
+ ] )
-@patch( 'vim.command', new_callable = ExtendedMock )
-def JumpToLocation_DifferentFile_NewOrExistingTab_AlreadyOpened_test(
- vim_command ):
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ def test_JumpToLocation_DifferentFile_Split_AllTabs_NotAlreadyOpened(
+ self, 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( 'different_uni¢𐍈d€' ),
+ current_buffer = VimBuffer( 'uni¢𐍈d€' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ target_name = os.path.realpath( 'different_uni¢𐍈d€' )
+
+ vimsupport.JumpToLocation( target_name,
+ 2,
+ 5,
+ 'tab',
+ 'split-or-existing-window' )
+
+ vim_command.assert_has_exact_calls( [
+ call( 'normal! m\'' ),
+ call( f'keepjumps tab split { target_name }' ),
+ call( 'normal! zz' )
+ ] )
+
+
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ def test_JumpToLocation_DifferentFile_Split_AllTabs_AlreadyOpened(
+ self, 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( 'different_uni¢𐍈d€' ),
+ 2,
+ 5,
+ 'tab',
+ 'split-or-existing-window' )
+
+ 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' )
+ ] )
+
+
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ def test_JumpToLocation_DifferentFile_NewOrExistingTab_NotAlreadyOpened(
+ self, vim_command ):
+
+ current_buffer = VimBuffer( 'uni¢𐍈d€' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ target_name = os.path.realpath( 'different_uni¢𐍈d€' )
+
+ vimsupport.JumpToLocation( target_name,
2,
5,
- 'belowright tab',
+ 'aboveleft vertical',
'new-or-existing-tab' )
- 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( f'keepjumps aboveleft vertical tabedit { target_name }' ),
call( 'normal! zz' )
] )
-@patch( 'ycm.tests.test_utils.VIM_VERSION', Version( 7, 4, 1578 ) )
-def VimVersionAtLeast_test():
- assert_that( vimsupport.VimVersionAtLeast( '7.3.414' ) )
- assert_that( vimsupport.VimVersionAtLeast( '7.4.1578' ) )
- assert_that( not vimsupport.VimVersionAtLeast( '7.4.1579' ) )
- assert_that( not vimsupport.VimVersionAtLeast( '7.4.1898' ) )
- assert_that( not vimsupport.VimVersionAtLeast( '8.1.278' ) )
+ @patch( 'vim.command', new_callable = ExtendedMock )
+ def test_JumpToLocation_DifferentFile_NewOrExistingTab_AlreadyOpened(
+ self, 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( 'different_uni¢𐍈d€' ),
+ 2,
+ 5,
+ 'belowright tab',
+ 'new-or-existing-tab' )
+
+ 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' )
+ ] )
+
+
+ @patch( 'ycm.tests.test_utils.VIM_VERSION', Version( 7, 4, 1578 ) )
+ def test_VimVersionAtLeast( self ):
+ assert_that( vimsupport.VimVersionAtLeast( '7.3.414' ) )
+ assert_that( vimsupport.VimVersionAtLeast( '7.4.1578' ) )
+ assert_that( not vimsupport.VimVersionAtLeast( '7.4.1579' ) )
+ assert_that( not vimsupport.VimVersionAtLeast( '7.4.1898' ) )
+ assert_that( not vimsupport.VimVersionAtLeast( '8.1.278' ) )
diff --git a/python/ycm/tests/youcompleteme_test.py b/python/ycm/tests/youcompleteme_test.py
index d86fed1e45..4f940eb954 100644
--- a/python/ycm/tests/youcompleteme_test.py
+++ b/python/ycm/tests/youcompleteme_test.py
@@ -30,6 +30,7 @@
from hamcrest import ( assert_that, contains_exactly, empty, equal_to,
has_entries, is_in, is_not, matches_regexp )
from unittest.mock import call, MagicMock, patch
+from unittest import TestCase
from ycm import vimsupport
from ycm.paths import _PathToPythonUsedDuringBuild
@@ -48,67 +49,6 @@
MockAsyncServerResponseException )
-@YouCompleteMeInstance()
-def YouCompleteMe_YcmCoreNotImported_test( ycm ):
- assert_that( 'ycm_core', is_not( is_in( sys.modules ) ) )
-
-
-@patch( 'ycm.vimsupport.PostVimMessage' )
-def YouCompleteMe_InvalidPythonInterpreterPath_test( post_vim_message ):
- with UserOptions( {
- 'g:ycm_server_python_interpreter': '/invalid/python/path' } ):
- try:
- ycm = YouCompleteMe()
-
- assert_that( ycm.IsServerAlive(), equal_to( False ) )
- post_vim_message.assert_called_once_with(
- "Unable to start the ycmd server. "
- "Path in 'g:ycm_server_python_interpreter' option does not point "
- "to a valid Python 3.6+. "
- "Correct the error then restart the server with ':YcmRestartServer'." )
-
- post_vim_message.reset_mock()
-
- SetVariableValue( 'g:ycm_server_python_interpreter',
- _PathToPythonUsedDuringBuild() )
- ycm.RestartServer()
-
- assert_that( ycm.IsServerAlive(), equal_to( True ) )
- post_vim_message.assert_called_once_with( 'Restarting ycmd server...' )
- finally:
- WaitUntilReady()
- StopServer( ycm )
-
-
-@patch( 'ycmd.utils.PathToFirstExistingExecutable', return_value = None )
-@patch( 'ycm.paths._EndsWithPython', return_value = False )
-@patch( 'ycm.vimsupport.PostVimMessage' )
-def YouCompleteMe_NoPythonInterpreterFound_test( post_vim_message, *args ):
- with UserOptions( {} ):
- try:
- with patch( 'ycmd.utils.ReadFile', side_effect = IOError ):
- ycm = YouCompleteMe()
-
- assert_that( ycm.IsServerAlive(), equal_to( False ) )
- post_vim_message.assert_called_once_with(
- "Unable to start the ycmd server. Cannot find Python 3.6+. "
- "Set the 'g:ycm_server_python_interpreter' option to a Python "
- "interpreter path. "
- "Correct the error then restart the server with ':YcmRestartServer'." )
-
- post_vim_message.reset_mock()
-
- SetVariableValue( 'g:ycm_server_python_interpreter',
- _PathToPythonUsedDuringBuild() )
- ycm.RestartServer()
-
- assert_that( ycm.IsServerAlive(), equal_to( True ) )
- post_vim_message.assert_called_once_with( 'Restarting ycmd server...' )
- finally:
- WaitUntilReady()
- StopServer( ycm )
-
-
def RunNotifyUserIfServerCrashed( ycm, post_vim_message, test ):
StopServer( ycm )
@@ -124,408 +64,6 @@ def RunNotifyUserIfServerCrashed( ycm, post_vim_message, test ):
test[ 'expected_message' ] )
-@YouCompleteMeInstance()
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def YouCompleteMe_NotifyUserIfServerCrashed_UnexpectedCore_test(
- post_vim_message, ycm ):
- message = (
- "The ycmd server SHUT DOWN \\(restart with ':YcmRestartServer'\\). "
- "Unexpected error while loading the YCM core library. Type "
- "':YcmToggleLogs ycmd_\\d+_stderr_.+.log' to check the logs." )
- RunNotifyUserIfServerCrashed( ycm, post_vim_message, {
- 'return_code': 3,
- 'expected_message': matches_regexp( message )
- } )
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def YouCompleteMe_NotifyUserIfServerCrashed_MissingCore_test(
- post_vim_message, ycm ):
- message = ( "The ycmd server SHUT DOWN (restart with ':YcmRestartServer'). "
- "YCM core library not detected; you need to compile YCM before "
- "using it. Follow the instructions in the documentation." )
- RunNotifyUserIfServerCrashed( ycm, post_vim_message, {
- 'return_code': 4,
- 'expected_message': equal_to( message )
- } )
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def YouCompleteMe_NotifyUserIfServerCrashed_OutdatedCore_test(
- post_vim_message, ycm ):
- message = ( "The ycmd server SHUT DOWN (restart with ':YcmRestartServer'). "
- "YCM core library too old; PLEASE RECOMPILE by running the "
- "install.py script. See the documentation for more details." )
- RunNotifyUserIfServerCrashed( ycm, post_vim_message, {
- 'return_code': 7,
- 'expected_message': equal_to( message )
- } )
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def YouCompleteMe_NotifyUserIfServerCrashed_UnexpectedExitCode_test(
- post_vim_message, ycm ):
- message = (
- "The ycmd server SHUT DOWN \\(restart with ':YcmRestartServer'\\). "
- "Unexpected exit code 1. Type "
- "':YcmToggleLogs ycmd_\\d+_stderr_.+.log' to check the logs." )
- RunNotifyUserIfServerCrashed( ycm, post_vim_message, {
- 'return_code': 1,
- 'expected_message': matches_regexp( message )
- } )
-
-
-@YouCompleteMeInstance( { 'g:ycm_extra_conf_vim_data': [ 'tempname()' ] } )
-def YouCompleteMe_DebugInfo_ServerRunning_test( ycm ):
- dir_of_script = os.path.dirname( os.path.abspath( __file__ ) )
- buf_name = os.path.join( dir_of_script, 'testdata', 'test.cpp' )
- extra_conf = os.path.join( dir_of_script, 'testdata', '.ycm_extra_conf.py' )
- _LoadExtraConfFile( extra_conf )
-
- current_buffer = VimBuffer( buf_name, filetype = 'cpp' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- assert_that(
- ycm.DebugInfo(),
- matches_regexp(
- 'Client logfile: .+\n'
- 'Server Python interpreter: .+\n'
- 'Server Python version: .+\n'
- 'Server has Clang support compiled in: (False|True)\n'
- 'Clang version: .+\n'
- 'Extra configuration file found and loaded\n'
- 'Extra configuration path: .*testdata[/\\\\]\\.ycm_extra_conf\\.py\n'
- '[\\w\\W]*'
- 'Server running at: .+\n'
- 'Server process ID: \\d+\n'
- 'Server logfiles:\n'
- ' .+\n'
- ' .+' )
- )
-
-
-@YouCompleteMeInstance()
-def YouCompleteMe_DebugInfo_ServerNotRunning_test( ycm ):
- StopServer( ycm )
-
- current_buffer = VimBuffer( 'current_buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- assert_that(
- ycm.DebugInfo(),
- matches_regexp(
- 'Client logfile: .+\n'
- 'Server errored, no debug info from server\n'
- 'Server running at: .+\n'
- 'Server process ID: \\d+\n'
- 'Server logfiles:\n'
- ' .+\n'
- ' .+' )
- )
-
-
-@YouCompleteMeInstance()
-def YouCompleteMe_OnVimLeave_RemoveClientLogfileByDefault_test( ycm ):
- client_logfile = ycm._client_logfile
- assert_that( os.path.isfile( client_logfile ),
- f'Logfile { client_logfile } does not exist.' )
- ycm.OnVimLeave()
- assert_that( not os.path.isfile( client_logfile ),
- f'Logfile { client_logfile } was not removed.' )
-
-
-@YouCompleteMeInstance( { 'g:ycm_keep_logfiles': 1 } )
-def YouCompleteMe_OnVimLeave_KeepClientLogfile_test( ycm ):
- client_logfile = ycm._client_logfile
- assert_that( os.path.isfile( client_logfile ),
- f'Logfile { client_logfile } does not exist.' )
- ycm.OnVimLeave()
- assert_that( os.path.isfile( client_logfile ),
- f'Logfile { client_logfile } was removed.' )
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.vimsupport.CloseBuffersForFilename', new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.OpenFilename', new_callable = ExtendedMock )
-def YouCompleteMe_ToggleLogs_WithParameters_test( open_filename,
- close_buffers_for_filename,
- ycm ):
- logfile_buffer = VimBuffer( ycm._client_logfile )
- with MockVimBuffers( [ logfile_buffer ], [ logfile_buffer ] ):
- ycm.ToggleLogs( 90,
- 'botright vertical',
- os.path.basename( ycm._client_logfile ),
- 'nonexisting_logfile',
- os.path.basename( ycm._server_stdout ) )
-
- open_filename.assert_has_exact_calls( [
- call( ycm._server_stdout, { 'size': 90,
- 'watch': True,
- 'fix': True,
- 'focus': False,
- 'position': 'end',
- 'mods': 'botright vertical' } )
- ] )
- close_buffers_for_filename.assert_has_exact_calls( [
- call( ycm._client_logfile )
- ] )
-
-
-@YouCompleteMeInstance()
-# Select the second item of the list which is the ycmd stderr logfile.
-@patch( 'ycm.vimsupport.SelectFromList', return_value = 1 )
-@patch( 'ycm.vimsupport.OpenFilename', new_callable = ExtendedMock )
-def YouCompleteMe_ToggleLogs_WithoutParameters_SelectLogfileNotAlreadyOpen_test(
- open_filename, select_from_list, ycm ):
-
- current_buffer = VimBuffer( 'current_buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- ycm.ToggleLogs( 0, '' )
-
- open_filename.assert_has_exact_calls( [
- call( ycm._server_stderr, { 'size': 12,
- 'watch': True,
- 'fix': True,
- 'focus': False,
- 'position': 'end',
- 'mods': '' } )
- ] )
-
-
-@YouCompleteMeInstance()
-# Select the third item of the list which is the ycmd stdout logfile.
-@patch( 'ycm.vimsupport.SelectFromList', return_value = 2 )
-@patch( 'ycm.vimsupport.CloseBuffersForFilename', new_callable = ExtendedMock )
-def YouCompleteMe_ToggleLogs_WithoutParameters_SelectLogfileAlreadyOpen_test(
- close_buffers_for_filename, select_from_list, ycm ):
-
- logfile_buffer = VimBuffer( ycm._server_stdout )
- with MockVimBuffers( [ logfile_buffer ], [ logfile_buffer ] ):
- ycm.ToggleLogs( 0, '' )
-
- close_buffers_for_filename.assert_has_exact_calls( [
- call( ycm._server_stdout )
- ] )
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.vimsupport.SelectFromList',
- side_effect = RuntimeError( 'Error message' ) )
-@patch( 'ycm.vimsupport.PostVimMessage' )
-def YouCompleteMe_ToggleLogs_WithoutParameters_NoSelection_test(
- post_vim_message, select_from_list, ycm ):
-
- current_buffer = VimBuffer( 'current_buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- ycm.ToggleLogs( 0, '' )
-
- assert_that(
- # Argument passed to PostVimMessage.
- post_vim_message.call_args[ 0 ][ 0 ],
- equal_to( 'Error message' )
- )
-
-
-@YouCompleteMeInstance()
-def YouCompleteMe_GetDefinedSubcommands_ListFromServer_test( ycm ):
- current_buffer = VimBuffer( 'buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with patch( 'ycm.client.base_request._JsonFromFuture',
- return_value = [ 'SomeCommand', 'AnotherCommand' ] ):
- assert_that(
- ycm.GetDefinedSubcommands(),
- contains_exactly(
- 'SomeCommand',
- 'AnotherCommand'
- )
- )
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.client.base_request._logger', autospec = True )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def YouCompleteMe_GetDefinedSubcommands_ErrorFromServer_test( post_vim_message,
- logger,
- ycm ):
- current_buffer = VimBuffer( 'buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with patch( 'ycm.client.base_request._JsonFromFuture',
- side_effect = ServerError( 'Server error' ) ):
- result = ycm.GetDefinedSubcommands()
-
- logger.exception.assert_called_with( 'Error while handling server response' )
- post_vim_message.assert_has_exact_calls( [
- call( 'Server error', truncate = False )
- ] )
- assert_that( result, empty() )
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def YouCompleteMe_ShowDetailedDiagnostic_MessageFromServer_test(
- post_vim_message, ycm ):
-
- current_buffer = VimBuffer( 'buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with patch( 'ycm.client.base_request._JsonFromFuture',
- return_value = { 'message': 'some_detailed_diagnostic' } ):
- ycm.ShowDetailedDiagnostic(),
-
- post_vim_message.assert_has_exact_calls( [
- call( 'some_detailed_diagnostic', warning = False )
- ] )
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def YouCompleteMe_ShowDetailedDiagnostic_Exception_test(
- post_vim_message, ycm ):
-
- current_buffer = VimBuffer( 'buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with patch( 'ycm.client.base_request._JsonFromFuture',
- side_effect = RuntimeError( 'Some exception' ) ):
- ycm.ShowDetailedDiagnostic(),
-
- post_vim_message.assert_has_exact_calls( [
- call( 'Some exception', truncate = False )
- ] )
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def YouCompleteMe_ShowDiagnostics_FiletypeNotSupported_test( post_vim_message,
- ycm ):
-
- current_buffer = VimBuffer( 'buffer', filetype = 'not_supported' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- ycm.ShowDiagnostics()
-
- post_vim_message.assert_called_once_with(
- 'Native filetype completion not supported for current file, '
- 'cannot force recompilation.', warning = False )
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
- return_value = True )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.SetLocationListForWindow', new_callable = ExtendedMock )
-def YouCompleteMe_ShowDiagnostics_NoDiagnosticsDetected_test(
- set_location_list_for_window,
- post_vim_message,
- filetype_completer_exists,
- ycm ):
-
- current_buffer = VimBuffer( 'buffer', filetype = 'cpp' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with patch( 'ycm.client.event_notification.EventNotification.Response',
- return_value = {} ):
- ycm.ShowDiagnostics()
-
- post_vim_message.assert_has_exact_calls( [
- call( 'Forcing compilation, this will block Vim until done.',
- warning = False ),
- call( 'Diagnostics refreshed', warning = False ),
- call( 'No warnings or errors detected.', warning = False )
- ] )
- set_location_list_for_window.assert_called_once_with( 1, [] )
-
-
-@YouCompleteMeInstance( { 'g:ycm_log_level': 'debug',
- 'g:ycm_keep_logfiles': 1,
- 'g:ycm_open_loclist_on_ycm_diags': 0 } )
-@patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
- return_value = True )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.SetLocationListForWindow', new_callable = ExtendedMock )
-def YouCompleteMe_ShowDiagnostics_DiagnosticsFound_DoNotOpenLocationList_test(
- set_location_list_for_window,
- post_vim_message,
- filetype_completer_exists,
- ycm ):
-
- diagnostic = {
- 'kind': 'ERROR',
- 'text': 'error text',
- 'location': {
- 'filepath': 'buffer',
- 'line_num': 19,
- 'column_num': 2
- }
- }
-
- current_buffer = VimBuffer( 'buffer',
- filetype = 'cpp',
- number = 3 )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with patch( 'ycm.client.event_notification.EventNotification.Response',
- return_value = [ diagnostic ] ):
- ycm.ShowDiagnostics()
-
- post_vim_message.assert_has_exact_calls( [
- call( 'Forcing compilation, this will block Vim until done.',
- warning = False ),
- call( 'Diagnostics refreshed', warning = False )
- ] )
- set_location_list_for_window.assert_called_once_with( 1, [ {
- 'bufnr': 3,
- 'lnum': 19,
- 'col': 2,
- 'text': 'error text',
- 'type': 'E',
- 'valid': 1
- } ] )
-
-
-@YouCompleteMeInstance( { 'g:ycm_open_loclist_on_ycm_diags': 1 } )
-@patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
- return_value = True )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.SetLocationListForWindow', new_callable = ExtendedMock )
-@patch( 'ycm.vimsupport.OpenLocationList', new_callable = ExtendedMock )
-def YouCompleteMe_ShowDiagnostics_DiagnosticsFound_OpenLocationList_test(
- open_location_list,
- set_location_list_for_window,
- post_vim_message,
- filetype_completer_exists,
- ycm ):
-
- diagnostic = {
- 'kind': 'ERROR',
- 'text': 'error text',
- 'location': {
- 'filepath': 'buffer',
- 'line_num': 19,
- 'column_num': 2
- }
- }
-
- current_buffer = VimBuffer( 'buffer',
- filetype = 'cpp',
- number = 3 )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- with patch( 'ycm.client.event_notification.EventNotification.Response',
- return_value = [ diagnostic ] ):
- ycm.ShowDiagnostics()
-
- post_vim_message.assert_has_exact_calls( [
- call( 'Forcing compilation, this will block Vim until done.',
- warning = False ),
- call( 'Diagnostics refreshed', warning = False )
- ] )
- set_location_list_for_window.assert_called_once_with( 1, [ {
- 'bufnr': 3,
- 'lnum': 19,
- 'col': 2,
- 'text': 'error text',
- 'type': 'E',
- 'valid': 1
- } ] )
- open_location_list.assert_called_once_with( focus = True )
-
-
def YouCompleteMe_UpdateDiagnosticInterface( ycm, post_vim_message, *args ):
contents = """int main() {
@@ -674,291 +212,540 @@ def YouCompleteMe_UpdateDiagnosticInterface( ycm, post_vim_message, *args ):
)
-@YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1,
- 'g:ycm_enable_diagnostic_signs': 1,
- 'g:ycm_enable_diagnostic_highlighting': 1 } )
-@patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
- return_value = True )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-@patch( 'ycm.client.event_notification.EventNotification.Done',
- return_value = True )
-def YouCompleteMe_UpdateDiagnosticInterface_OldVim_test(
- request_done, post_vim_message, filetype_completer_exists, ycm ):
- YouCompleteMe_UpdateDiagnosticInterface( ycm, post_vim_message )
-
-
-@YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1,
- 'g:ycm_enable_diagnostic_signs': 1,
- 'g:ycm_enable_diagnostic_highlighting': 1 } )
-@patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
- return_value = True )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-@patch( 'ycm.tests.test_utils.VIM_VERSION', Version( 8, 1, 614 ) )
-@patch( 'ycm.client.event_notification.EventNotification.Done',
- return_value = True )
-def YouCompleteMe_UpdateDiagnosticInterface_NewVim_test(
- request_done, post_vim_message, filetype_completer_exists, ycm ):
- YouCompleteMe_UpdateDiagnosticInterface( ycm, post_vim_message )
-
-
-@YouCompleteMeInstance( { 'g:ycm_enable_diagnostic_highlighting': 1 } )
-def YouCompleteMe_UpdateMatches_ClearDiagnosticMatchesInNewBuffer_test( ycm ):
- current_buffer = VimBuffer( 'buffer',
- filetype = 'c',
- number = 5 )
+class YouCompleteMeTest( TestCase ):
+ @YouCompleteMeInstance()
+ def test_YouCompleteMe_YcmCoreNotImported( self, ycm ):
+ assert_that( 'ycm_core', is_not( is_in( sys.modules ) ) )
- test_utils.VIM_MATCHES_FOR_WINDOW[ 1 ] = [
- VimMatch( 'YcmWarningSection', '\\%3l\\%5c\\_.\\{-}\\%3l\\%7c' ),
- VimMatch( 'YcmWarningSection', '\\%3l\\%3c\\_.\\{-}\\%3l\\%9c' ),
- VimMatch( 'YcmErrorSection', '\\%3l\\%8c' )
- ]
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- ycm.UpdateMatches()
+ @patch( 'ycm.vimsupport.PostVimMessage' )
+ def test_YouCompleteMe_InvalidPythonInterpreterPath( self, post_vim_message ):
+ with UserOptions( {
+ 'g:ycm_server_python_interpreter': '/invalid/python/path' } ):
+ try:
+ ycm = YouCompleteMe()
- assert_that( test_utils.VIM_MATCHES_FOR_WINDOW,
- has_entries( { 1: empty() } ) )
+ assert_that( ycm.IsServerAlive(), equal_to( False ) )
+ post_vim_message.assert_called_once_with(
+ "Unable to start the ycmd server. "
+ "Path in 'g:ycm_server_python_interpreter' option does not point "
+ "to a valid Python 3.6+. "
+ "Correct the error then restart the server with "
+ "':YcmRestartServer'." )
+
+ post_vim_message.reset_mock()
+
+ SetVariableValue( 'g:ycm_server_python_interpreter',
+ _PathToPythonUsedDuringBuild() )
+ ycm.RestartServer()
+
+ assert_that( ycm.IsServerAlive(), equal_to( True ) )
+ post_vim_message.assert_called_once_with( 'Restarting ycmd server...' )
+ finally:
+ WaitUntilReady()
+ StopServer( ycm )
+
+
+ @patch( 'ycmd.utils.PathToFirstExistingExecutable', return_value = None )
+ @patch( 'ycm.paths._EndsWithPython', return_value = False )
+ @patch( 'ycm.vimsupport.PostVimMessage' )
+ def test_YouCompleteMe_NoPythonInterpreterFound(
+ self, post_vim_message, *args ):
+ with UserOptions( {} ):
+ try:
+ with patch( 'ycmd.utils.ReadFile', side_effect = IOError ):
+ ycm = YouCompleteMe()
+
+ assert_that( ycm.IsServerAlive(), equal_to( False ) )
+ post_vim_message.assert_called_once_with(
+ "Unable to start the ycmd server. Cannot find Python 3.6+. "
+ "Set the 'g:ycm_server_python_interpreter' option to a Python "
+ "interpreter path. "
+ "Correct the error then restart the server with "
+ "':YcmRestartServer'." )
+
+ post_vim_message.reset_mock()
+
+ SetVariableValue( 'g:ycm_server_python_interpreter',
+ _PathToPythonUsedDuringBuild() )
+ ycm.RestartServer()
+
+ assert_that( ycm.IsServerAlive(), equal_to( True ) )
+ post_vim_message.assert_called_once_with( 'Restarting ycmd server...' )
+ finally:
+ WaitUntilReady()
+ StopServer( ycm )
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_YouCompleteMe_NotifyUserIfServerCrashed_UnexpectedCore(
+ self, ycm, post_vim_message ):
+ message = (
+ "The ycmd server SHUT DOWN \\(restart with ':YcmRestartServer'\\). "
+ "Unexpected error while loading the YCM core library. Type "
+ "':YcmToggleLogs ycmd_\\d+_stderr_.+.log' to check the logs." )
+ RunNotifyUserIfServerCrashed( ycm, post_vim_message, {
+ 'return_code': 3,
+ 'expected_message': matches_regexp( message )
+ } )
-@YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1,
- 'g:ycm_always_populate_location_list': 1,
- 'g:ycm_show_diagnostics_ui': 0,
- 'g:ycm_enable_diagnostic_highlighting': 1 } )
-@patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
- return_value = True )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def YouCompleteMe_AsyncDiagnosticUpdate_UserDisabled_test(
- post_vim_message,
- filetype_completer_exists,
- ycm ):
- diagnostics = [
- {
- 'kind': 'ERROR',
- 'text': 'error text in current buffer',
- 'location': {
- 'filepath': '/current',
- 'line_num': 1,
- 'column_num': 1
- },
- 'location_extent': {
- 'start': {
- 'filepath': '/current',
- 'line_num': 1,
- 'column_num': 1,
- },
- 'end': {
- 'filepath': '/current',
- 'line_num': 1,
- 'column_num': 1,
- }
- },
- 'ranges': []
- },
- ]
- current_buffer = VimBuffer( '/current',
- filetype = 'ycmtest',
- contents = [ 'current' ] * 10,
- number = 1 )
- buffers = [ current_buffer ]
- windows = [ current_buffer ]
-
- # Register each buffer internally with YCM
- for current in buffers:
- with MockVimBuffers( buffers, [ current ] ):
- ycm.OnFileReadyToParse()
- with patch( 'ycm.vimsupport.SetLocationListForWindow',
- new_callable = ExtendedMock ) as set_location_list_for_window:
- with MockVimBuffers( buffers, windows ):
- ycm.UpdateWithNewDiagnosticsForFile( '/current', diagnostics )
-
- post_vim_message.assert_has_exact_calls( [] )
- set_location_list_for_window.assert_has_exact_calls( [] )
-
- assert_that(
- test_utils.VIM_MATCHES_FOR_WINDOW,
- empty()
- )
-
-
-@YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1,
- 'g:ycm_always_populate_location_list': 1,
- 'g:ycm_enable_diagnostic_highlighting': 1 } )
-@patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
- return_value = True )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def YouCompleteMe_AsyncDiagnosticUpdate_SingleFile_test(
- post_vim_message,
- filetype_completer_exists,
- ycm ):
+ @YouCompleteMeInstance()
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_YouCompleteMe_NotifyUserIfServerCrashed_MissingCore(
+ self, ycm, post_vim_message ):
+ message = ( "The ycmd server SHUT DOWN (restart with ':YcmRestartServer'). "
+ "YCM core library not detected; you need to compile YCM before "
+ "using it. Follow the instructions in the documentation." )
+ RunNotifyUserIfServerCrashed( ycm, post_vim_message, {
+ 'return_code': 4,
+ 'expected_message': equal_to( message )
+ } )
- # This test simulates asynchronous diagnostic updates associated with a single
- # file (e.g. Translation Unit), but where the actual errors refer to other
- # open files and other non-open files. This is not strictly invalid, nor is it
- # completely normal, but it is supported and does work.
- # Contrast with the next test which sends the diagnostics filewise, which is
- # what the language server protocol will do.
+ @YouCompleteMeInstance()
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_YouCompleteMe_NotifyUserIfServerCrashed_OutdatedCore(
+ self, ycm, post_vim_message ):
+ message = ( "The ycmd server SHUT DOWN (restart with ':YcmRestartServer'). "
+ "YCM core library too old; PLEASE RECOMPILE by running the "
+ "install.py script. See the documentation for more details." )
+ RunNotifyUserIfServerCrashed( ycm, post_vim_message, {
+ 'return_code': 7,
+ 'expected_message': equal_to( message )
+ } )
- diagnostics = [
- {
- 'kind': 'ERROR',
- 'text': 'error text in current buffer',
- 'location': {
- 'filepath': '/current',
- 'line_num': 1,
- 'column_num': 1
- },
- 'location_extent': {
- 'start': {
- 'filepath': '/current',
- 'line_num': 1,
- 'column_num': 1,
- },
- 'end': {
- 'filepath': '/current',
- 'line_num': 1,
- 'column_num': 1,
- }
- },
- 'ranges': []
- },
- {
- 'kind': 'ERROR',
- 'text': 'error text in hidden buffer',
- 'location': {
- 'filepath': '/has_diags',
- 'line_num': 4,
- 'column_num': 2
- },
- 'location_extent': {
- 'start': {
- 'filepath': '/has_diags',
- 'line_num': 4,
- 'column_num': 2,
- },
- 'end': {
- 'filepath': '/has_diags',
- 'line_num': 4,
- 'column_num': 2,
- }
- },
- 'ranges': []
- },
- {
- 'kind': 'ERROR',
- 'text': 'error text in buffer not open in Vim',
- 'location': {
- 'filepath': '/not_open',
- 'line_num': 8,
- 'column_num': 4
- },
- 'location_extent': {
- 'start': {
- 'filepath': '/not_open',
- 'line_num': 8,
- 'column_num': 4,
- },
- 'end': {
- 'filepath': '/not_open',
- 'line_num': 8,
- 'column_num': 4,
- }
- },
- 'ranges': []
- }
- ]
- current_buffer = VimBuffer( '/current',
- filetype = 'ycmtest',
- contents = [ 'current' ] * 10,
- number = 1 )
- no_diags_buffer = VimBuffer( '/no_diags',
- filetype = 'ycmtest',
- contents = [ 'nodiags' ] * 10,
- number = 2 )
- hidden_buffer = VimBuffer( '/has_diags',
- filetype = 'ycmtest',
- contents = [ 'hasdiags' ] * 10,
- number = 3 )
-
- buffers = [ current_buffer, no_diags_buffer, hidden_buffer ]
- windows = [ current_buffer, no_diags_buffer ]
-
- # Register each buffer internally with YCM
- for current in buffers:
- with MockVimBuffers( buffers, [ current ] ):
- ycm.OnFileReadyToParse()
+ @YouCompleteMeInstance()
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_YouCompleteMe_NotifyUserIfServerCrashed_UnexpectedExitCode(
+ self, ycm, post_vim_message ):
+ message = (
+ "The ycmd server SHUT DOWN \\(restart with ':YcmRestartServer'\\). "
+ "Unexpected exit code 1. Type "
+ "':YcmToggleLogs ycmd_\\d+_stderr_.+.log' to check the logs." )
+ RunNotifyUserIfServerCrashed( ycm, post_vim_message, {
+ 'return_code': 1,
+ 'expected_message': matches_regexp( message )
+ } )
- with patch( 'ycm.vimsupport.SetLocationListForWindow',
- new_callable = ExtendedMock ) as set_location_list_for_window:
- with MockVimBuffers( buffers, windows ):
- ycm.UpdateWithNewDiagnosticsForFile( '/current', diagnostics )
- # We update the diagnostic on the current cursor position
- post_vim_message.assert_has_exact_calls( [
- call( "error text in current buffer", truncate = True, warning = False ),
- ] )
+ @YouCompleteMeInstance( { 'g:ycm_extra_conf_vim_data': [ 'tempname()' ] } )
+ def test_YouCompleteMe_DebugInfo_ServerRunning( self, ycm ):
+ dir_of_script = os.path.dirname( os.path.abspath( __file__ ) )
+ buf_name = os.path.join( dir_of_script, 'testdata', 'test.cpp' )
+ extra_conf = os.path.join( dir_of_script, 'testdata', '.ycm_extra_conf.py' )
+ _LoadExtraConfFile( extra_conf )
- # Ensure we included all the diags though
- set_location_list_for_window.assert_has_exact_calls( [
- call( 1, [
- {
- 'lnum': 1,
- 'col': 1,
- 'bufnr': 1,
- 'valid': 1,
- 'type': 'E',
- 'text': 'error text in current buffer',
- },
- {
- 'lnum': 4,
- 'col': 2,
- 'bufnr': 3,
- 'valid': 1,
- 'type': 'E',
- 'text': 'error text in hidden buffer',
- },
- {
- 'lnum': 8,
- 'col': 4,
- 'bufnr': -1, # sic: Our mocked bufnr function actually returns -1,
- # even though YCM is passing "create if needed".
- # FIXME? we shouldn't do that, and we should pass
- # filename instead
- 'valid': 1,
- 'type': 'E',
- 'text': 'error text in buffer not open in Vim'
- }
- ] )
- ] )
+ current_buffer = VimBuffer( buf_name, filetype = 'cpp' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ assert_that(
+ ycm.DebugInfo(),
+ matches_regexp(
+ 'Client logfile: .+\n'
+ 'Server Python interpreter: .+\n'
+ 'Server Python version: .+\n'
+ 'Server has Clang support compiled in: (False|True)\n'
+ 'Clang version: .+\n'
+ 'Extra configuration file found and loaded\n'
+ 'Extra configuration path: .*testdata[/\\\\]\\.ycm_extra_conf\\.py\n'
+ '[\\w\\W]*'
+ 'Server running at: .+\n'
+ 'Server process ID: \\d+\n'
+ 'Server logfiles:\n'
+ ' .+\n'
+ ' .+' )
+ )
- assert_that(
- test_utils.VIM_MATCHES_FOR_WINDOW,
- has_entries( {
- 1: contains_exactly(
- VimMatch( 'YcmErrorSection', '\\%1l\\%1c\\_.\\{-}\\%1l\\%1c' )
+
+ @YouCompleteMeInstance()
+ def test_YouCompleteMe_DebugInfo_ServerNotRunning( self, ycm ):
+ StopServer( ycm )
+
+ current_buffer = VimBuffer( 'current_buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ assert_that(
+ ycm.DebugInfo(),
+ matches_regexp(
+ 'Client logfile: .+\n'
+ 'Server errored, no debug info from server\n'
+ 'Server running at: .+\n'
+ 'Server process ID: \\d+\n'
+ 'Server logfiles:\n'
+ ' .+\n'
+ ' .+' )
)
- } )
- )
-@YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1,
- 'g:ycm_always_populate_location_list': 1,
- 'g:ycm_enable_diagnostic_highlighting': 1 } )
-@patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
- return_value = True )
-@patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
-def YouCompleteMe_AsyncDiagnosticUpdate_PerFile_test(
+ @YouCompleteMeInstance()
+ def test_YouCompleteMe_OnVimLeave_RemoveClientLogfileByDefault( self, ycm ):
+ client_logfile = ycm._client_logfile
+ assert_that( os.path.isfile( client_logfile ),
+ f'Logfile { client_logfile } does not exist.' )
+ ycm.OnVimLeave()
+ assert_that( not os.path.isfile( client_logfile ),
+ f'Logfile { client_logfile } was not removed.' )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_keep_logfiles': 1 } )
+ def test_YouCompleteMe_OnVimLeave_KeepClientLogfile( self, ycm ):
+ client_logfile = ycm._client_logfile
+ assert_that( os.path.isfile( client_logfile ),
+ f'Logfile { client_logfile } does not exist.' )
+ ycm.OnVimLeave()
+ assert_that( os.path.isfile( client_logfile ),
+ f'Logfile { client_logfile } was removed.' )
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.vimsupport.CloseBuffersForFilename',
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.OpenFilename', new_callable = ExtendedMock )
+ def test_YouCompleteMe_ToggleLogs_WithParameters(
+ self, ycm, open_filename, close_buffers_for_filename ):
+ logfile_buffer = VimBuffer( ycm._client_logfile )
+ with MockVimBuffers( [ logfile_buffer ], [ logfile_buffer ] ):
+ ycm.ToggleLogs( 90,
+ 'botright vertical',
+ os.path.basename( ycm._client_logfile ),
+ 'nonexisting_logfile',
+ os.path.basename( ycm._server_stdout ) )
+
+ open_filename.assert_has_exact_calls( [
+ call( ycm._server_stdout, { 'size': 90,
+ 'watch': True,
+ 'fix': True,
+ 'focus': False,
+ 'position': 'end',
+ 'mods': 'botright vertical' } )
+ ] )
+ close_buffers_for_filename.assert_has_exact_calls( [
+ call( ycm._client_logfile )
+ ] )
+
+
+ @YouCompleteMeInstance()
+ # Select the second item of the list which is the ycmd stderr logfile.
+ @patch( 'ycm.vimsupport.SelectFromList', return_value = 1 )
+ @patch( 'ycm.vimsupport.OpenFilename', new_callable = ExtendedMock )
+ def test_YouCompleteMe_ToggleLogs_WithoutParameters_SelectLogfileNotAlreadyOpen( # noqa
+ self, ycm, open_filename, *args ):
+
+ current_buffer = VimBuffer( 'current_buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ ycm.ToggleLogs( 0, '' )
+
+ open_filename.assert_has_exact_calls( [
+ call( ycm._server_stderr, { 'size': 12,
+ 'watch': True,
+ 'fix': True,
+ 'focus': False,
+ 'position': 'end',
+ 'mods': '' } )
+ ] )
+
+
+ @YouCompleteMeInstance()
+ # Select the third item of the list which is the ycmd stdout logfile.
+ @patch( 'ycm.vimsupport.SelectFromList', return_value = 2 )
+ @patch( 'ycm.vimsupport.CloseBuffersForFilename',
+ new_callable = ExtendedMock )
+ def test_YouCompleteMe_ToggleLogs_WithoutParameters_SelectLogfileAlreadyOpen(
+ self, ycm, close_buffers_for_filename, *args ):
+
+ logfile_buffer = VimBuffer( ycm._server_stdout )
+ with MockVimBuffers( [ logfile_buffer ], [ logfile_buffer ] ):
+ ycm.ToggleLogs( 0, '' )
+
+ close_buffers_for_filename.assert_has_exact_calls( [
+ call( ycm._server_stdout )
+ ] )
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.vimsupport.SelectFromList',
+ side_effect = RuntimeError( 'Error message' ) )
+ @patch( 'ycm.vimsupport.PostVimMessage' )
+ def test_YouCompleteMe_ToggleLogs_WithoutParameters_NoSelection(
+ self, ycm, post_vim_message, *args ):
+
+ current_buffer = VimBuffer( 'current_buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ ycm.ToggleLogs( 0, '' )
+
+ assert_that(
+ # Argument passed to PostVimMessage.
+ post_vim_message.call_args[ 0 ][ 0 ],
+ equal_to( 'Error message' )
+ )
+
+
+ @YouCompleteMeInstance()
+ def test_YouCompleteMe_GetDefinedSubcommands_ListFromServer( self, ycm ):
+ current_buffer = VimBuffer( 'buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with patch( 'ycm.client.base_request._JsonFromFuture',
+ return_value = [ 'SomeCommand', 'AnotherCommand' ] ):
+ assert_that(
+ ycm.GetDefinedSubcommands(),
+ contains_exactly(
+ 'SomeCommand',
+ 'AnotherCommand'
+ )
+ )
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.client.base_request._logger', autospec = True )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_YouCompleteMe_GetDefinedSubcommands_ErrorFromServer(
+ self, ycm, post_vim_message, logger ):
+ current_buffer = VimBuffer( 'buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with patch( 'ycm.client.base_request._JsonFromFuture',
+ side_effect = ServerError( 'Server error' ) ):
+ result = ycm.GetDefinedSubcommands()
+
+ logger.exception.assert_called_with(
+ 'Error while handling server response' )
+ post_vim_message.assert_has_exact_calls( [
+ call( 'Server error', truncate = False )
+ ] )
+ assert_that( result, empty() )
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_YouCompleteMe_ShowDetailedDiagnostic_MessageFromServer(
+ self, ycm, post_vim_message ):
+
+ current_buffer = VimBuffer( 'buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with patch( 'ycm.client.base_request._JsonFromFuture',
+ return_value = { 'message': 'some_detailed_diagnostic' } ):
+ ycm.ShowDetailedDiagnostic(),
+
+ post_vim_message.assert_has_exact_calls( [
+ call( 'some_detailed_diagnostic', warning = False )
+ ] )
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_YouCompleteMe_ShowDetailedDiagnostic_Exception(
+ self, ycm, post_vim_message ):
+
+ current_buffer = VimBuffer( 'buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with patch( 'ycm.client.base_request._JsonFromFuture',
+ side_effect = RuntimeError( 'Some exception' ) ):
+ ycm.ShowDetailedDiagnostic(),
+
+ post_vim_message.assert_has_exact_calls( [
+ call( 'Some exception', truncate = False )
+ ] )
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_YouCompleteMe_ShowDiagnostics_FiletypeNotSupported(
+ self, ycm, post_vim_message ):
+
+ current_buffer = VimBuffer( 'buffer', filetype = 'not_supported' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ ycm.ShowDiagnostics()
+
+ post_vim_message.assert_called_once_with(
+ 'Native filetype completion not supported for current file, '
+ 'cannot force recompilation.', warning = False )
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
+ return_value = True )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.SetLocationListForWindow',
+ new_callable = ExtendedMock )
+ def test_YouCompleteMe_ShowDiagnostics_NoDiagnosticsDetected(
+ self,
+ ycm,
+ set_location_list_for_window,
+ post_vim_message,
+ *args ):
+
+ current_buffer = VimBuffer( 'buffer', filetype = 'cpp' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with patch( 'ycm.client.event_notification.EventNotification.Response',
+ return_value = {} ):
+ ycm.ShowDiagnostics()
+
+ post_vim_message.assert_has_exact_calls( [
+ call( 'Forcing compilation, this will block Vim until done.',
+ warning = False ),
+ call( 'Diagnostics refreshed', warning = False ),
+ call( 'No warnings or errors detected.', warning = False )
+ ] )
+ set_location_list_for_window.assert_called_once_with( 1, [] )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_log_level': 'debug',
+ 'g:ycm_keep_logfiles': 1,
+ 'g:ycm_open_loclist_on_ycm_diags': 0 } )
+ @patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
+ return_value = True )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.SetLocationListForWindow',
+ new_callable = ExtendedMock )
+ def test_YouCompleteMe_ShowDiagnostics_DiagnosticsFound_DoNotOpenLocationList(
+ self,
+ ycm,
+ set_location_list_for_window,
post_vim_message,
- filetype_completer_exists,
- ycm ):
+ *args ):
+ diagnostic = {
+ 'kind': 'ERROR',
+ 'text': 'error text',
+ 'location': {
+ 'filepath': 'buffer',
+ 'line_num': 19,
+ 'column_num': 2
+ }
+ }
- # This test simulates asynchronous diagnostic updates which are delivered per
- # file, including files which are open and files which are not.
+ current_buffer = VimBuffer( 'buffer',
+ filetype = 'cpp',
+ number = 3 )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with patch( 'ycm.client.event_notification.EventNotification.Response',
+ return_value = [ diagnostic ] ):
+ ycm.ShowDiagnostics()
+
+ post_vim_message.assert_has_exact_calls( [
+ call( 'Forcing compilation, this will block Vim until done.',
+ warning = False ),
+ call( 'Diagnostics refreshed', warning = False )
+ ] )
+ set_location_list_for_window.assert_called_once_with( 1, [ {
+ 'bufnr': 3,
+ 'lnum': 19,
+ 'col': 2,
+ 'text': 'error text',
+ 'type': 'E',
+ 'valid': 1
+ } ] )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_open_loclist_on_ycm_diags': 1 } )
+ @patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
+ return_value = True )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.SetLocationListForWindow',
+ new_callable = ExtendedMock )
+ @patch( 'ycm.vimsupport.OpenLocationList', new_callable = ExtendedMock )
+ def test_YouCompleteMe_ShowDiagnostics_DiagnosticsFound_OpenLocationList(
+ self,
+ ycm,
+ open_location_list,
+ set_location_list_for_window,
+ post_vim_message,
+ *args ):
- # Ordered to ensure that the calls to update are deterministic
- diagnostics_per_file = [
- ( '/current', [ {
+ diagnostic = {
+ 'kind': 'ERROR',
+ 'text': 'error text',
+ 'location': {
+ 'filepath': 'buffer',
+ 'line_num': 19,
+ 'column_num': 2
+ }
+ }
+
+ current_buffer = VimBuffer( 'buffer',
+ filetype = 'cpp',
+ number = 3 )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ with patch( 'ycm.client.event_notification.EventNotification.Response',
+ return_value = [ diagnostic ] ):
+ ycm.ShowDiagnostics()
+
+ post_vim_message.assert_has_exact_calls( [
+ call( 'Forcing compilation, this will block Vim until done.',
+ warning = False ),
+ call( 'Diagnostics refreshed', warning = False )
+ ] )
+ set_location_list_for_window.assert_called_once_with( 1, [ {
+ 'bufnr': 3,
+ 'lnum': 19,
+ 'col': 2,
+ 'text': 'error text',
+ 'type': 'E',
+ 'valid': 1
+ } ] )
+ open_location_list.assert_called_once_with( focus = True )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1,
+ 'g:ycm_enable_diagnostic_signs': 1,
+ 'g:ycm_enable_diagnostic_highlighting': 1 } )
+ @patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
+ return_value = True )
+ @patch( 'ycm.client.event_notification.EventNotification.Done',
+ return_value = True )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_YouCompleteMe_UpdateDiagnosticInterface_OldVim(
+ self, ycm, post_vim_message, *args ):
+ YouCompleteMe_UpdateDiagnosticInterface( ycm, post_vim_message )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1,
+ 'g:ycm_enable_diagnostic_signs': 1,
+ 'g:ycm_enable_diagnostic_highlighting': 1 } )
+ @patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
+ return_value = True )
+ @patch( 'ycm.tests.test_utils.VIM_VERSION', Version( 8, 1, 614 ) )
+ @patch( 'ycm.client.event_notification.EventNotification.Done',
+ return_value = True )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_YouCompleteMe_UpdateDiagnosticInterface_NewVim(
+ self, ycm, post_vim_message, *args ):
+ YouCompleteMe_UpdateDiagnosticInterface( ycm, post_vim_message )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_enable_diagnostic_highlighting': 1 } )
+ def test_YouCompleteMe_UpdateMatches_ClearDiagnosticMatchesInNewBuffer(
+ self, ycm ):
+ current_buffer = VimBuffer( 'buffer',
+ filetype = 'c',
+ number = 5 )
+
+ test_utils.VIM_MATCHES_FOR_WINDOW[ 1 ] = [
+ VimMatch( 'YcmWarningSection', '\\%3l\\%5c\\_.\\{-}\\%3l\\%7c' ),
+ VimMatch( 'YcmWarningSection', '\\%3l\\%3c\\_.\\{-}\\%3l\\%9c' ),
+ VimMatch( 'YcmErrorSection', '\\%3l\\%8c' )
+ ]
+
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ ycm.UpdateMatches()
+
+ assert_that( test_utils.VIM_MATCHES_FOR_WINDOW,
+ has_entries( { 1: empty() } ) )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1,
+ 'g:ycm_always_populate_location_list': 1,
+ 'g:ycm_show_diagnostics_ui': 0,
+ 'g:ycm_enable_diagnostic_highlighting': 1 } )
+ @patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
+ return_value = True )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_YouCompleteMe_AsyncDiagnosticUpdate_UserDisabled(
+ self,
+ ycm,
+ post_vim_message,
+ *args ):
+ diagnostics = [
+ {
'kind': 'ERROR',
'text': 'error text in current buffer',
'location': {
@@ -978,53 +765,100 @@ def YouCompleteMe_AsyncDiagnosticUpdate_PerFile_test(
'column_num': 1,
}
},
- 'ranges': [],
- } ] ),
- ( '/separate_window', [ {
+ 'ranges': []
+ },
+ ]
+ current_buffer = VimBuffer( '/current',
+ filetype = 'ycmtest',
+ contents = [ 'current' ] * 10,
+ number = 1 )
+ buffers = [ current_buffer ]
+ windows = [ current_buffer ]
+
+ # Register each buffer internally with YCM
+ for current in buffers:
+ with MockVimBuffers( buffers, [ current ] ):
+ ycm.OnFileReadyToParse()
+ with patch( 'ycm.vimsupport.SetLocationListForWindow',
+ new_callable = ExtendedMock ) as set_location_list_for_window:
+ with MockVimBuffers( buffers, windows ):
+ ycm.UpdateWithNewDiagnosticsForFile( '/current', diagnostics )
+
+ post_vim_message.assert_has_exact_calls( [] )
+ set_location_list_for_window.assert_has_exact_calls( [] )
+
+ assert_that(
+ test_utils.VIM_MATCHES_FOR_WINDOW,
+ empty()
+ )
+
+
+ @YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1,
+ 'g:ycm_always_populate_location_list': 1,
+ 'g:ycm_enable_diagnostic_highlighting': 1 } )
+ @patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
+ return_value = True )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_YouCompleteMe_AsyncDiagnosticUpdate_SingleFile(
+ self,
+ ycm,
+ post_vim_message,
+ *args ):
+
+ # This test simulates asynchronous diagnostic updates associated with a
+ # single file (e.g. Translation Unit), but where the actual errors refer to
+ # other open files and other non-open files. This is not strictly invalid,
+ # nor is it completely normal, but it is supported and does work.
+
+ # Contrast with the next test which sends the diagnostics filewise, which
+ # is what the language server protocol will do.
+
+ diagnostics = [
+ {
'kind': 'ERROR',
- 'text': 'error text in a buffer open in a separate window',
+ 'text': 'error text in current buffer',
'location': {
- 'filepath': '/separate_window',
- 'line_num': 3,
- 'column_num': 3
+ 'filepath': '/current',
+ 'line_num': 1,
+ 'column_num': 1
},
'location_extent': {
'start': {
- 'filepath': '/separate_window',
- 'line_num': 3,
- 'column_num': 3,
+ 'filepath': '/current',
+ 'line_num': 1,
+ 'column_num': 1,
},
'end': {
- 'filepath': '/separate_window',
- 'line_num': 3,
- 'column_num': 3,
+ 'filepath': '/current',
+ 'line_num': 1,
+ 'column_num': 1,
}
},
'ranges': []
- } ] ),
- ( '/hidden', [ {
+ },
+ {
'kind': 'ERROR',
'text': 'error text in hidden buffer',
'location': {
- 'filepath': '/hidden',
+ 'filepath': '/has_diags',
'line_num': 4,
'column_num': 2
},
'location_extent': {
'start': {
- 'filepath': '/hidden',
+ 'filepath': '/has_diags',
'line_num': 4,
'column_num': 2,
},
'end': {
- 'filepath': '/hidden',
+ 'filepath': '/has_diags',
'line_num': 4,
'column_num': 2,
}
},
'ranges': []
- } ] ),
- ( '/not_open', [ {
+ },
+ {
'kind': 'ERROR',
'text': 'error text in buffer not open in Vim',
'location': {
@@ -1045,252 +879,450 @@ def YouCompleteMe_AsyncDiagnosticUpdate_PerFile_test(
}
},
'ranges': []
- } ] )
- ]
-
- current_buffer = VimBuffer( '/current',
- filetype = 'ycmtest',
- contents = [ 'current' ] * 10,
- number = 1 )
- no_diags_buffer = VimBuffer( '/no_diags',
- filetype = 'ycmtest',
- contents = [ 'no_diags' ] * 10,
- number = 2 )
- separate_window = VimBuffer( '/separate_window',
+ }
+ ]
+
+ current_buffer = VimBuffer( '/current',
+ filetype = 'ycmtest',
+ contents = [ 'current' ] * 10,
+ number = 1 )
+ no_diags_buffer = VimBuffer( '/no_diags',
+ filetype = 'ycmtest',
+ contents = [ 'nodiags' ] * 10,
+ number = 2 )
+ hidden_buffer = VimBuffer( '/has_diags',
filetype = 'ycmtest',
- contents = [ 'separate_window' ] * 10,
+ contents = [ 'hasdiags' ] * 10,
number = 3 )
- hidden_buffer = VimBuffer( '/hidden',
- filetype = 'ycmtest',
- contents = [ 'hidden' ] * 10,
- number = 4 )
- buffers = [
- current_buffer,
- no_diags_buffer,
- separate_window,
- hidden_buffer
- ]
- windows = [
- current_buffer,
- no_diags_buffer,
- separate_window
- ]
-
- # Register each buffer internally with YCM
- for current in buffers:
- with MockVimBuffers( buffers, [ current ] ):
- ycm.OnFileReadyToParse()
- with patch( 'ycm.vimsupport.SetLocationListForWindow',
- new_callable = ExtendedMock ) as set_location_list_for_window:
- with MockVimBuffers( buffers, windows ):
- for filename, diagnostics in diagnostics_per_file:
- ycm.UpdateWithNewDiagnosticsForFile( filename, diagnostics )
+ buffers = [ current_buffer, no_diags_buffer, hidden_buffer ]
+ windows = [ current_buffer, no_diags_buffer ]
- # We update the diagnostic on the current cursor position
- post_vim_message.assert_has_exact_calls( [
- call( "error text in current buffer", truncate = True, warning = False ),
- ] )
+ # Register each buffer internally with YCM
+ for current in buffers:
+ with MockVimBuffers( buffers, [ current ] ):
+ ycm.OnFileReadyToParse()
- # Ensure we included all the diags though
- set_location_list_for_window.assert_has_exact_calls( [
- call( 1, [
- {
- 'lnum': 1,
- 'col': 1,
- 'bufnr': 1,
- 'valid': 1,
- 'type': 'E',
- 'text': 'error text in current buffer',
- },
- ] ),
+ with patch( 'ycm.vimsupport.SetLocationListForWindow',
+ new_callable = ExtendedMock ) as set_location_list_for_window:
+ with MockVimBuffers( buffers, windows ):
+ ycm.UpdateWithNewDiagnosticsForFile( '/current', diagnostics )
- call( 3, [
- {
- 'lnum': 3,
- 'col': 3,
- 'bufnr': 3,
- 'valid': 1,
- 'type': 'E',
- 'text': 'error text in a buffer open in a separate window',
- },
+ # We update the diagnostic on the current cursor position
+ post_vim_message.assert_has_exact_calls( [
+ call( "error text in current buffer", truncate = True, warning = False ),
] )
- ] )
-
- # FIXME: diagnostic matches in windows other than the current one are not
- # updated.
- assert_that(
- test_utils.VIM_MATCHES_FOR_WINDOW,
- has_entries( {
- 1: contains_exactly(
- VimMatch( 'YcmErrorSection', '\\%1l\\%1c\\_.\\{-}\\%1l\\%1c' )
- )
- } )
- )
+ # Ensure we included all the diags though
+ set_location_list_for_window.assert_has_exact_calls( [
+ call( 1, [
+ {
+ 'lnum': 1,
+ 'col': 1,
+ 'bufnr': 1,
+ 'valid': 1,
+ 'type': 'E',
+ 'text': 'error text in current buffer',
+ },
+ {
+ 'lnum': 4,
+ 'col': 2,
+ 'bufnr': 3,
+ 'valid': 1,
+ 'type': 'E',
+ 'text': 'error text in hidden buffer',
+ },
+ {
+ 'lnum': 8,
+ 'col': 4,
+ 'bufnr': -1, # sic: Our mocked bufnr function actually returns -1,
+ # even though YCM is passing "create if needed".
+ # FIXME? we shouldn't do that, and we should pass
+ # filename instead
+ 'valid': 1,
+ 'type': 'E',
+ 'text': 'error text in buffer not open in Vim'
+ }
+ ] )
+ ] )
-@YouCompleteMeInstance()
-def YouCompleteMe_OnPeriodicTick_ServerNotRunning_test( ycm ):
- with patch.object( ycm, 'IsServerAlive', return_value = False ):
- assert_that( ycm.OnPeriodicTick(), equal_to( False ) )
+ assert_that(
+ test_utils.VIM_MATCHES_FOR_WINDOW,
+ has_entries( {
+ 1: contains_exactly(
+ VimMatch( 'YcmErrorSection', '\\%1l\\%1c\\_.\\{-}\\%1l\\%1c' )
+ )
+ } )
+ )
-@YouCompleteMeInstance()
-def YouCompleteMe_OnPeriodicTick_ServerNotReady_test( ycm ):
- with patch.object( ycm, 'IsServerAlive', return_value = True ):
- with patch.object( ycm, 'IsServerReady', return_value = False ):
- assert_that( ycm.OnPeriodicTick(), equal_to( True ) )
+ @YouCompleteMeInstance( { 'g:ycm_echo_current_diagnostic': 1,
+ 'g:ycm_always_populate_location_list': 1,
+ 'g:ycm_enable_diagnostic_highlighting': 1 } )
+ @patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
+ return_value = True )
+ @patch( 'ycm.vimsupport.PostVimMessage', new_callable = ExtendedMock )
+ def test_YouCompleteMe_AsyncDiagnosticUpdate_PerFile(
+ self,
+ ycm,
+ post_vim_message,
+ *args ):
+
+ # This test simulates asynchronous diagnostic updates which are delivered
+ # per file, including files which are open and files which are not.
+
+ # Ordered to ensure that the calls to update are deterministic
+ diagnostics_per_file = [
+ ( '/current', [ {
+ 'kind': 'ERROR',
+ 'text': 'error text in current buffer',
+ 'location': {
+ 'filepath': '/current',
+ 'line_num': 1,
+ 'column_num': 1
+ },
+ 'location_extent': {
+ 'start': {
+ 'filepath': '/current',
+ 'line_num': 1,
+ 'column_num': 1,
+ },
+ 'end': {
+ 'filepath': '/current',
+ 'line_num': 1,
+ 'column_num': 1,
+ }
+ },
+ 'ranges': [],
+ } ] ),
+ ( '/separate_window', [ {
+ 'kind': 'ERROR',
+ 'text': 'error text in a buffer open in a separate window',
+ 'location': {
+ 'filepath': '/separate_window',
+ 'line_num': 3,
+ 'column_num': 3
+ },
+ 'location_extent': {
+ 'start': {
+ 'filepath': '/separate_window',
+ 'line_num': 3,
+ 'column_num': 3,
+ },
+ 'end': {
+ 'filepath': '/separate_window',
+ 'line_num': 3,
+ 'column_num': 3,
+ }
+ },
+ 'ranges': []
+ } ] ),
+ ( '/hidden', [ {
+ 'kind': 'ERROR',
+ 'text': 'error text in hidden buffer',
+ 'location': {
+ 'filepath': '/hidden',
+ 'line_num': 4,
+ 'column_num': 2
+ },
+ 'location_extent': {
+ 'start': {
+ 'filepath': '/hidden',
+ 'line_num': 4,
+ 'column_num': 2,
+ },
+ 'end': {
+ 'filepath': '/hidden',
+ 'line_num': 4,
+ 'column_num': 2,
+ }
+ },
+ 'ranges': []
+ } ] ),
+ ( '/not_open', [ {
+ 'kind': 'ERROR',
+ 'text': 'error text in buffer not open in Vim',
+ 'location': {
+ 'filepath': '/not_open',
+ 'line_num': 8,
+ 'column_num': 4
+ },
+ 'location_extent': {
+ 'start': {
+ 'filepath': '/not_open',
+ 'line_num': 8,
+ 'column_num': 4,
+ },
+ 'end': {
+ 'filepath': '/not_open',
+ 'line_num': 8,
+ 'column_num': 4,
+ }
+ },
+ 'ranges': []
+ } ] )
+ ]
+
+ current_buffer = VimBuffer( '/current',
+ filetype = 'ycmtest',
+ contents = [ 'current' ] * 10,
+ number = 1 )
+ no_diags_buffer = VimBuffer( '/no_diags',
+ filetype = 'ycmtest',
+ contents = [ 'no_diags' ] * 10,
+ number = 2 )
+ separate_window = VimBuffer( '/separate_window',
+ filetype = 'ycmtest',
+ contents = [ 'separate_window' ] * 10,
+ number = 3 )
+ hidden_buffer = VimBuffer( '/hidden',
+ filetype = 'ycmtest',
+ contents = [ 'hidden' ] * 10,
+ number = 4 )
+ buffers = [
+ current_buffer,
+ no_diags_buffer,
+ separate_window,
+ hidden_buffer
+ ]
+ windows = [
+ current_buffer,
+ no_diags_buffer,
+ separate_window
+ ]
+
+ # Register each buffer internally with YCM
+ for current in buffers:
+ with MockVimBuffers( buffers, [ current ] ):
+ ycm.OnFileReadyToParse()
+
+ with patch( 'ycm.vimsupport.SetLocationListForWindow',
+ new_callable = ExtendedMock ) as set_location_list_for_window:
+ with MockVimBuffers( buffers, windows ):
+ for filename, diagnostics in diagnostics_per_file:
+ ycm.UpdateWithNewDiagnosticsForFile( filename, diagnostics )
+
+ # We update the diagnostic on the current cursor position
+ post_vim_message.assert_has_exact_calls( [
+ call( "error text in current buffer", truncate = True, warning = False ),
+ ] )
+
+ # Ensure we included all the diags though
+ set_location_list_for_window.assert_has_exact_calls( [
+ call( 1, [
+ {
+ 'lnum': 1,
+ 'col': 1,
+ 'bufnr': 1,
+ 'valid': 1,
+ 'type': 'E',
+ 'text': 'error text in current buffer',
+ },
+ ] ),
+
+ call( 3, [
+ {
+ 'lnum': 3,
+ 'col': 3,
+ 'bufnr': 3,
+ 'valid': 1,
+ 'type': 'E',
+ 'text': 'error text in a buffer open in a separate window',
+ },
+ ] )
+ ] )
+ # FIXME: diagnostic matches in windows other than the current one are not
+ # updated.
+ assert_that(
+ test_utils.VIM_MATCHES_FOR_WINDOW,
+ has_entries( {
+ 1: contains_exactly(
+ VimMatch( 'YcmErrorSection', '\\%1l\\%1c\\_.\\{-}\\%1l\\%1c' )
+ )
+ } )
+ )
-@YouCompleteMeInstance()
-@patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
- return_value = True )
-@patch( 'ycm.client.base_request._ValidateResponseObject', return_value = True )
-@patch( 'ycm.client.base_request.BaseRequest.PostDataToHandlerAsync' )
-def YouCompleteMe_OnPeriodicTick_DontRetry_test(
- post_data_to_handler_async,
- validate_response_object,
- filetype_completer_exists,
- ycm ):
-
- current_buffer = VimBuffer( '/current',
- filetype = 'ycmtest',
- number = 1 )
-
- # Create the request and make the first poll; we expect no response
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ):
- assert_that( ycm.OnPeriodicTick(), equal_to( True ) )
- post_data_to_handler_async.assert_called()
-
- assert ycm._message_poll_requests[ 'ycmtest' ] is not None
- post_data_to_handler_async.reset_mock()
-
- # OK that sent the request, now poll to check if it is complete (say it is
- # not)
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ) as v:
- mock_response = MockAsyncServerResponseInProgress()
- with patch.dict( ycm._message_poll_requests, {} ):
- ycm._message_poll_requests[ 'ycmtest' ] = MessagesPoll( v.current.buffer )
- ycm._message_poll_requests[ 'ycmtest' ]._response_future = mock_response
- mock_future = ycm._message_poll_requests[ 'ycmtest' ]._response_future
- poll_again = ycm.OnPeriodicTick()
- mock_future.done.assert_called()
- mock_future.result.assert_not_called()
- assert_that( poll_again, equal_to( True ) )
-
- # Poll again, but return a response (telling us to stop polling)
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ) as v:
- mock_response = MockAsyncServerResponseDone( False )
- with patch.dict( ycm._message_poll_requests, {} ):
- ycm._message_poll_requests[ 'ycmtest' ] = MessagesPoll( v.current.buffer )
- ycm._message_poll_requests[ 'ycmtest' ]._response_future = mock_response
- mock_future = ycm._message_poll_requests[ 'ycmtest' ]._response_future
- poll_again = ycm.OnPeriodicTick()
- mock_future.done.assert_called()
- mock_future.result.assert_called()
- post_data_to_handler_async.assert_not_called()
- # We reset and don't poll anymore
- assert_that( ycm._message_poll_requests[ 'ycmtest' ] is None )
- assert_that( poll_again, equal_to( False ) )
-
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
- return_value = True )
-@patch( 'ycm.client.base_request._ValidateResponseObject', return_value = True )
-@patch( 'ycm.client.base_request.BaseRequest.PostDataToHandlerAsync' )
-def YouCompleteMe_OnPeriodicTick_Exception_test( post_data_to_handler_async,
- validate_response_object,
- filetype_completer_exists,
- ycm ):
-
- current_buffer = VimBuffer( '/current',
- filetype = 'ycmtest',
- number = 1 )
-
- # Create the request and make the first poll; we expect no response
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ):
- assert_that( ycm.OnPeriodicTick(), equal_to( True ) )
- post_data_to_handler_async.assert_called()
-
- post_data_to_handler_async.reset_mock()
-
- # Poll again, but return an exception response
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ) as v:
- mock_response = MockAsyncServerResponseException( RuntimeError( 'test' ) )
- with patch.dict( ycm._message_poll_requests, {} ):
- ycm._message_poll_requests[ 'ycmtest' ] = MessagesPoll( v.current.buffer )
- ycm._message_poll_requests[ 'ycmtest' ]._response_future = mock_response
- mock_future = ycm._message_poll_requests[ 'ycmtest' ]._response_future
+
+ @YouCompleteMeInstance()
+ def test_YouCompleteMe_OnPeriodicTick_ServerNotRunning( self, ycm ):
+ with patch.object( ycm, 'IsServerAlive', return_value = False ):
assert_that( ycm.OnPeriodicTick(), equal_to( False ) )
- mock_future.done.assert_called()
- mock_future.result.assert_called()
- post_data_to_handler_async.assert_not_called()
- # We reset and don't poll anymore
- assert_that( ycm._message_poll_requests[ 'ycmtest' ] is None )
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
- return_value = True )
-@patch( 'ycm.client.base_request._ValidateResponseObject', return_value = True )
-@patch( 'ycm.client.base_request.BaseRequest.PostDataToHandlerAsync' )
-@patch( 'ycm.client.messages_request._HandlePollResponse' )
-def YouCompleteMe_OnPeriodicTick_ValidResponse_test( handle_poll_response,
- post_data_to_handler_async,
- validate_response_object,
- filetype_completer_exists,
- ycm ):
-
- current_buffer = VimBuffer( '/current',
- filetype = 'ycmtest',
- number = 1 )
-
- # Create the request and make the first poll; we expect no response
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ):
- assert_that( ycm.OnPeriodicTick(), equal_to( True ) )
- post_data_to_handler_async.assert_called()
-
- post_data_to_handler_async.reset_mock()
-
- # Poll again, and return a _proper_ response (finally!).
- # Note, _HandlePollResponse is tested independently (for simplicity)
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ) as v:
- mock_response = MockAsyncServerResponseDone( [] )
- with patch.dict( ycm._message_poll_requests, {} ):
- ycm._message_poll_requests[ 'ycmtest' ] = MessagesPoll( v.current.buffer )
- ycm._message_poll_requests[ 'ycmtest' ]._response_future = mock_response
- mock_future = ycm._message_poll_requests[ 'ycmtest' ]._response_future
+
+
+ @YouCompleteMeInstance()
+ def test_YouCompleteMe_OnPeriodicTick_ServerNotReady( self, ycm ):
+ with patch.object( ycm, 'IsServerAlive', return_value = True ):
+ with patch.object( ycm, 'IsServerReady', return_value = False ):
+ assert_that( ycm.OnPeriodicTick(), equal_to( True ) )
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
+ return_value = True )
+ @patch( 'ycm.client.base_request._ValidateResponseObject',
+ return_value = True )
+ @patch( 'ycm.client.base_request.BaseRequest.PostDataToHandlerAsync' )
+ def test_YouCompleteMe_OnPeriodicTick_DontRetry(
+ self,
+ ycm,
+ post_data_to_handler_async,
+ *args ):
+
+ current_buffer = VimBuffer( '/current',
+ filetype = 'ycmtest',
+ number = 1 )
+
+ # Create the request and make the first poll; we expect no response
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ):
+ assert_that( ycm.OnPeriodicTick(), equal_to( True ) )
+ post_data_to_handler_async.assert_called()
+
+ assert ycm._message_poll_requests[ 'ycmtest' ] is not None
+ post_data_to_handler_async.reset_mock()
+
+ # OK that sent the request, now poll to check if it is complete (say it is
+ # not)
+ with MockVimBuffers( [ current_buffer ],
+ [ current_buffer ],
+ ( 1, 1 ) ) as v:
+ mock_response = MockAsyncServerResponseInProgress()
+ with patch.dict( ycm._message_poll_requests, {} ):
+ ycm._message_poll_requests[ 'ycmtest' ] = MessagesPoll(
+ v.current.buffer )
+ ycm._message_poll_requests[ 'ycmtest' ]._response_future = mock_response
+ mock_future = ycm._message_poll_requests[ 'ycmtest' ]._response_future
+ poll_again = ycm.OnPeriodicTick()
+ mock_future.done.assert_called()
+ mock_future.result.assert_not_called()
+ assert_that( poll_again, equal_to( True ) )
+
+ # Poll again, but return a response (telling us to stop polling)
+ with MockVimBuffers( [ current_buffer ],
+ [ current_buffer ],
+ ( 1, 1 ) ) as v:
+ mock_response = MockAsyncServerResponseDone( False )
+ with patch.dict( ycm._message_poll_requests, {} ):
+ ycm._message_poll_requests[ 'ycmtest' ] = MessagesPoll(
+ v.current.buffer )
+ ycm._message_poll_requests[ 'ycmtest' ]._response_future = mock_response
+ mock_future = ycm._message_poll_requests[ 'ycmtest' ]._response_future
+ poll_again = ycm.OnPeriodicTick()
+ mock_future.done.assert_called()
+ mock_future.result.assert_called()
+ post_data_to_handler_async.assert_not_called()
+ # We reset and don't poll anymore
+ assert_that( ycm._message_poll_requests[ 'ycmtest' ] is None )
+ assert_that( poll_again, equal_to( False ) )
+
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
+ return_value = True )
+ @patch( 'ycm.client.base_request._ValidateResponseObject',
+ return_value = True )
+ @patch( 'ycm.client.base_request.BaseRequest.PostDataToHandlerAsync' )
+ def test_YouCompleteMe_OnPeriodicTick_Exception(
+ self,
+ ycm,
+ post_data_to_handler_async,
+ *args ):
+
+ current_buffer = VimBuffer( '/current',
+ filetype = 'ycmtest',
+ number = 1 )
+
+ # Create the request and make the first poll; we expect no response
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ):
+ assert_that( ycm.OnPeriodicTick(), equal_to( True ) )
+ post_data_to_handler_async.assert_called()
+
+ post_data_to_handler_async.reset_mock()
+
+ # Poll again, but return an exception response
+ with MockVimBuffers( [ current_buffer ],
+ [ current_buffer ],
+ ( 1, 1 ) ) as v:
+ mock_response = MockAsyncServerResponseException(
+ RuntimeError( 'test' ) )
+ with patch.dict( ycm._message_poll_requests, {} ):
+ ycm._message_poll_requests[ 'ycmtest' ] = MessagesPoll(
+ v.current.buffer )
+ ycm._message_poll_requests[ 'ycmtest' ]._response_future = mock_response
+ mock_future = ycm._message_poll_requests[ 'ycmtest' ]._response_future
+ assert_that( ycm.OnPeriodicTick(), equal_to( False ) )
+ mock_future.done.assert_called()
+ mock_future.result.assert_called()
+ post_data_to_handler_async.assert_not_called()
+ # We reset and don't poll anymore
+ assert_that( ycm._message_poll_requests[ 'ycmtest' ] is None )
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.youcompleteme.YouCompleteMe.FiletypeCompleterExistsForFiletype',
+ return_value = True )
+ @patch( 'ycm.client.base_request._ValidateResponseObject',
+ return_value = True )
+ @patch( 'ycm.client.base_request.BaseRequest.PostDataToHandlerAsync' )
+ @patch( 'ycm.client.messages_request._HandlePollResponse' )
+ def test_YouCompleteMe_OnPeriodicTick_ValidResponse(
+ self, ycm, handle_poll_response, post_data_to_handler_async, *args ):
+
+ current_buffer = VimBuffer( '/current',
+ filetype = 'ycmtest',
+ number = 1 )
+
+ # Create the request and make the first poll; we expect no response
+ with MockVimBuffers( [ current_buffer ],
+ [ current_buffer ],
+ ( 1, 1 ) ):
assert_that( ycm.OnPeriodicTick(), equal_to( True ) )
- handle_poll_response.assert_called()
- mock_future.done.assert_called()
- mock_future.result.assert_called()
- post_data_to_handler_async.assert_called() # Poll again!
- assert_that( ycm._message_poll_requests[ 'ycmtest' ] is not None )
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.client.completion_request.CompletionRequest.OnCompleteDone' )
-def YouCompleteMe_OnCompleteDone_CompletionRequest_test( on_complete_done,
- ycm ):
- current_buffer = VimBuffer( 'current_buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ):
- ycm.SendCompletionRequest()
- ycm.OnCompleteDone()
- on_complete_done.assert_called()
-
-
-@YouCompleteMeInstance()
-@patch( 'ycm.client.completion_request.CompletionRequest.OnCompleteDone' )
-def YouCompleteMe_OnCompleteDone_NoCompletionRequest_test( on_complete_done,
- ycm ):
- ycm.OnCompleteDone()
- on_complete_done.assert_not_called()
-
-
-@YouCompleteMeInstance()
-def YouCompleteMe_ShouldResendFileParseRequest_NoParseRequest_test( ycm ):
- current_buffer = VimBuffer( 'current_buffer' )
- with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
- assert_that( ycm.ShouldResendFileParseRequest(), equal_to( False ) )
+ post_data_to_handler_async.assert_called()
+
+ post_data_to_handler_async.reset_mock()
+
+ # Poll again, and return a _proper_ response (finally!).
+ # Note, _HandlePollResponse is tested independently (for simplicity)
+ with MockVimBuffers( [ current_buffer ],
+ [ current_buffer ],
+ ( 1, 1 ) ) as v:
+ mock_response = MockAsyncServerResponseDone( [] )
+ with patch.dict( ycm._message_poll_requests, {} ):
+ ycm._message_poll_requests[ 'ycmtest' ] = MessagesPoll(
+ v.current.buffer )
+ ycm._message_poll_requests[ 'ycmtest' ]._response_future = mock_response
+ mock_future = ycm._message_poll_requests[ 'ycmtest' ]._response_future
+ assert_that( ycm.OnPeriodicTick(), equal_to( True ) )
+ handle_poll_response.assert_called()
+ mock_future.done.assert_called()
+ mock_future.result.assert_called()
+ post_data_to_handler_async.assert_called() # Poll again!
+ assert_that( ycm._message_poll_requests[ 'ycmtest' ] is not None )
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.client.completion_request.CompletionRequest.OnCompleteDone' )
+ def test_YouCompleteMe_OnCompleteDone_CompletionRequest(
+ self, ycm, on_complete_done ):
+ current_buffer = VimBuffer( 'current_buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ], ( 1, 1 ) ):
+ ycm.SendCompletionRequest()
+ ycm.OnCompleteDone()
+ on_complete_done.assert_called()
+
+
+ @YouCompleteMeInstance()
+ @patch( 'ycm.client.completion_request.CompletionRequest.OnCompleteDone' )
+ def test_YouCompleteMe_OnCompleteDone_NoCompletionRequest(
+ self, ycm, on_complete_done ):
+ ycm.OnCompleteDone()
+ on_complete_done.assert_not_called()
+
+
+ @YouCompleteMeInstance()
+ def test_YouCompleteMe_ShouldResendFileParseRequest_NoParseRequest(
+ self, ycm ):
+ current_buffer = VimBuffer( 'current_buffer' )
+ with MockVimBuffers( [ current_buffer ], [ current_buffer ] ):
+ assert_that( ycm.ShouldResendFileParseRequest(), equal_to( False ) )
diff --git a/run_tests.py b/run_tests.py
index b99b90ba26..628ccce6be 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -20,13 +20,7 @@
#
# Pip knows how to install this correctly so that it doesn't matter where in
# sys.path the path is.
-python_path = [ p.join( DIR_OF_THIRD_PARTY, 'pythonfutures' ),
- p.join( DIR_OF_THIRD_PARTY, 'requests-futures' ),
- p.join( DIR_OF_THIRD_PARTY, 'requests_deps', 'chardet' ),
- p.join( DIR_OF_THIRD_PARTY, 'requests_deps', 'certifi' ),
- p.join( DIR_OF_THIRD_PARTY, 'requests_deps', 'idna' ),
- p.join( DIR_OF_THIRD_PARTY, 'requests_deps', 'requests' ),
- p.join( DIR_OF_THIRD_PARTY, 'requests_deps', 'urllib3', 'src' ),
+python_path = [ p.join( DIR_OF_THIS_SCRIPT, 'python' ),
p.join( DIR_OF_THIRD_PARTY, 'ycmd' ) ]
if os.environ.get( 'PYTHONPATH' ):
python_path.append( os.environ[ 'PYTHONPATH' ] )
@@ -56,12 +50,12 @@ def ParseArguments():
help = 'Dump the PYTHONPATH required to run tests '
'manually, then exit.' )
- parsed_args, pytests_args = parser.parse_known_args()
+ parsed_args, unittest_args = parser.parse_known_args()
if 'COVERAGE' in os.environ:
parsed_args.coverage = ( os.environ[ 'COVERAGE' ] == 'true' )
- return parsed_args, pytests_args
+ return parsed_args, unittest_args
def BuildYcmdLibs( args ):
@@ -72,22 +66,31 @@ def BuildYcmdLibs( args ):
] )
-def PytestTests( parsed_args, extra_pytests_args ):
- pytests_args = []
+def UnittestTests( parsed_args, extra_unittest_args ):
+ unittest_args = [ '-cb' ]
+ prefer_regular = any( p.isfile( arg ) for arg in extra_unittest_args )
+ if not prefer_regular:
+ unittest_args += [ '-p', '*_test.py' ]
- if parsed_args.coverage:
- pytests_args += [ '--cov=ycm' ]
+ if extra_unittest_args:
+ unittest_args.extend( extra_unittest_args )
+ if not ( prefer_regular and extra_unittest_args ):
+ unittest_args.append( '-s' )
+ unittest_args.append( p.join( DIR_OF_THIS_SCRIPT, 'python', 'ycm', 'tests' ) )
- if extra_pytests_args:
- pytests_args.extend( extra_pytests_args )
+ if parsed_args.coverage:
+ executable = [ sys.executable, '-m', 'coverage', 'run' ]
else:
- pytests_args.append( p.join( DIR_OF_THIS_SCRIPT, 'python' ) )
+ executable = [ sys.executable ]
- subprocess.check_call( [ sys.executable, '-m', 'pytest' ] + pytests_args )
+ unittest = [ '-m', 'unittest' ]
+ if not prefer_regular:
+ unittest.append( 'discover' )
+ subprocess.check_call( executable + unittest + unittest_args )
def Main():
- ( parsed_args, pytests_args ) = ParseArguments()
+ ( parsed_args, unittest_args ) = ParseArguments()
if parsed_args.dump_path:
print( os.environ[ 'PYTHONPATH' ] )
sys.exit()
@@ -96,7 +99,7 @@ def Main():
RunFlake8()
BuildYcmdLibs( parsed_args )
- PytestTests( parsed_args, pytests_args )
+ UnittestTests( parsed_args, unittest_args )
if __name__ == "__main__":