123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667 |
- #!/usr/bin/env python
- #
- # Copyright (C) 2015 YouCompleteMe contributors
- #
- # This file is part of YouCompleteMe.
- #
- # YouCompleteMe is free software: you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation, either version 3 of the License, or
- # (at your option) any later version.
- #
- # YouCompleteMe is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
- from ycm.test_utils import MockVimModule
- MockVimModule()
- from ycm import vimsupport
- from nose.tools import eq_
- from mock import MagicMock, call, patch
- def ReplaceChunk_SingleLine_Repl_1_test():
- # Replace with longer range
- # 12345678901234567
- result_buffer = [ "This is a string" ]
- start, end = _BuildLocations( 1, 1, 1, 5 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
- end,
- 'How long',
- 0,
- 0,
- result_buffer )
- eq_( [ "How long is a string" ], result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, 4 )
- # and replace again, using delta
- start, end = _BuildLocations( 1, 10, 1, 11 )
- ( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
- start,
- end,
- ' piece of ',
- line_offset,
- char_offset,
- result_buffer )
- line_offset += new_line_offset
- char_offset += new_char_offset
- eq_( [ 'How long is a piece of string' ], result_buffer )
- eq_( new_line_offset, 0 )
- eq_( new_char_offset, 9 )
- eq_( line_offset, 0 )
- eq_( char_offset, 13 )
- # and once more, for luck
- start, end = _BuildLocations( 1, 11, 1, 17 )
- ( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
- start,
- end,
- 'pie',
- line_offset,
- char_offset,
- result_buffer )
- line_offset += new_line_offset
- char_offset += new_char_offset
- eq_( ['How long is a piece of pie' ], result_buffer )
- eq_( new_line_offset, 0 )
- eq_( new_char_offset, -3 )
- eq_( line_offset, 0 )
- eq_( char_offset, 10 )
- def ReplaceChunk_SingleLine_Repl_2_test():
- # Replace with shorter range
- # 12345678901234567
- result_buffer = [ "This is a string" ]
- start, end = _BuildLocations( 1, 11, 1, 17 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
- end,
- 'test',
- 0,
- 0,
- result_buffer )
- eq_( [ "This is a test" ], result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, -2 )
- def ReplaceChunk_SingleLine_Repl_3_test():
- # Replace with equal range
- # 12345678901234567
- result_buffer = [ "This is a string" ]
- start, end = _BuildLocations( 1, 6, 1, 8 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
- end,
- 'be',
- 0,
- 0,
- result_buffer )
- eq_( [ "This be a string" ], result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, 0 )
- def ReplaceChunk_SingleLine_Add_1_test():
- # Insert at start
- result_buffer = [ "is a string" ]
- start, end = _BuildLocations( 1, 1, 1, 1 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
- end,
- 'This ',
- 0,
- 0,
- result_buffer )
- eq_( [ "This is a string" ], result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, 5 )
- def ReplaceChunk_SingleLine_Add_2_test():
- # Insert at end
- result_buffer = [ "This is a " ]
- start, end = _BuildLocations( 1, 11, 1, 11 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
- end,
- 'string',
- 0,
- 0,
- result_buffer )
- eq_( [ "This is a string" ], result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, 6 )
- def ReplaceChunk_SingleLine_Add_3_test():
- # Insert in the middle
- result_buffer = [ "This is a string" ]
- start, end = _BuildLocations( 1, 8, 1, 8 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
- end,
- ' not',
- 0,
- 0,
- result_buffer )
- eq_( [ "This is not a string" ], result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, 4 )
- def ReplaceChunk_SingleLine_Del_1_test():
- # Delete from start
- result_buffer = [ "This is a string" ]
- start, end = _BuildLocations( 1, 1, 1, 6 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
- end,
- '',
- 0,
- 0,
- result_buffer )
- eq_( [ "is a string" ], result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, -5 )
- def ReplaceChunk_SingleLine_Del_2_test():
- # Delete from end
- result_buffer = [ "This is a string" ]
- start, end = _BuildLocations( 1, 10, 1, 18 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
- end,
- '',
- 0,
- 0,
- result_buffer )
- eq_( [ "This is a" ], result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, -8 )
- def ReplaceChunk_SingleLine_Del_3_test():
- # Delete from middle
- result_buffer = [ "This is not a string" ]
- start, end = _BuildLocations( 1, 9, 1, 13 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
- end,
- '',
- 0,
- 0,
- result_buffer )
- eq_( [ "This is a string" ], result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, -4 )
- def ReplaceChunk_RemoveSingleLine_test():
- result_buffer = [ "aAa", "aBa", "aCa" ]
- start, end = _BuildLocations( 2, 1, 3, 1 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, '',
- 0, 0, result_buffer )
- expected_buffer = [ "aAa", "aCa" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, -1 )
- eq_( char_offset, 0 )
- def ReplaceChunk_SingleToMultipleLines_test():
- result_buffer = [ "aAa",
- "aBa",
- "aCa" ]
- start, end = _BuildLocations( 2, 2, 2, 2 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'Eb\nbF',
- 0, 0, result_buffer )
- expected_buffer = [ "aAa",
- "aEb",
- "bFBa",
- "aCa" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, 1 )
- eq_( char_offset, 1 )
- # now make another change to the "2nd" line
- start, end = _BuildLocations( 2, 3, 2, 4 )
- ( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
- start,
- end,
- 'cccc',
- line_offset,
- char_offset,
- result_buffer )
- line_offset += new_line_offset
- char_offset += new_char_offset
- eq_( [ "aAa", "aEb", "bFBcccc", "aCa" ], result_buffer )
- eq_( line_offset, 1 )
- eq_( char_offset, 4 )
- def ReplaceChunk_SingleToMultipleLines2_test():
- result_buffer = [ "aAa", "aBa", "aCa" ]
- start, end = _BuildLocations( 2, 2, 2, 2 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
- end,
- 'Eb\nbFb\nG',
- 0,
- 0,
- result_buffer )
- expected_buffer = [ "aAa", "aEb", "bFb", "GBa", "aCa" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, 2 )
- eq_( char_offset, 0 )
- def ReplaceChunk_SingleToMultipleLines3_test():
- result_buffer = [ "aAa", "aBa", "aCa" ]
- start, end = _BuildLocations( 2, 2, 2, 2 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
- end,
- 'Eb\nbFb\nbGb',
- 0,
- 0,
- result_buffer )
- expected_buffer = [ "aAa", "aEb", "bFb", "bGbBa", "aCa" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, 2 )
- eq_( char_offset, 2 )
- def ReplaceChunk_SingleToMultipleLinesReplace_test():
- result_buffer = [ "aAa", "aBa", "aCa" ]
- start, end = _BuildLocations( 1, 2, 1, 4 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
- end,
- 'Eb\nbFb\nbGb',
- 0,
- 0,
- result_buffer )
- expected_buffer = [ "aEb", "bFb", "bGb", "aBa", "aCa" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, 2 )
- eq_( char_offset, 0 )
- def ReplaceChunk_SingleToMultipleLinesReplace_2_test():
- result_buffer = [ "aAa",
- "aBa",
- "aCa" ]
- start, end = _BuildLocations( 1, 2, 1, 4 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
- end,
- 'Eb\nbFb\nbGb',
- 0,
- 0,
- result_buffer )
- expected_buffer = [ "aEb",
- "bFb",
- "bGb",
- "aBa",
- "aCa" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, 2 )
- eq_( char_offset, 0 )
- # now do a subsequent change (insert at end of line "1")
- start, end = _BuildLocations( 1, 4, 1, 4 )
- ( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
- start,
- end,
- 'cccc',
- line_offset,
- char_offset,
- result_buffer )
- line_offset += new_line_offset
- char_offset += new_char_offset
- eq_( [ "aEb",
- "bFb",
- "bGbcccc",
- "aBa",
- "aCa" ], result_buffer )
- eq_( line_offset, 2 )
- eq_( char_offset, 4 )
- def ReplaceChunk_MultipleLinesToSingleLine_test():
- result_buffer = [ "aAa", "aBa", "aCaaaa" ]
- start, end = _BuildLocations( 2, 2, 3, 2 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'E',
- 0, 0, result_buffer )
- expected_buffer = [ "aAa", "aECaaaa" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, -1 )
- eq_( char_offset, 1 )
- # make another modification applying offsets
- start, end = _BuildLocations( 3, 3, 3, 4 )
- ( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
- start,
- end,
- 'cccc',
- line_offset,
- char_offset,
- result_buffer )
- line_offset += new_line_offset
- char_offset += new_char_offset
- eq_( [ "aAa", "aECccccaaa" ], result_buffer )
- eq_( line_offset, -1 )
- eq_( char_offset, 4 )
- # and another, for luck
- start, end = _BuildLocations( 3, 4, 3, 5 )
- ( new_line_offset, new_char_offset ) = vimsupport.ReplaceChunk(
- start,
- end,
- 'dd\ndd',
- line_offset,
- char_offset,
- result_buffer )
- line_offset += new_line_offset
- char_offset += new_char_offset
- eq_( [ "aAa", "aECccccdd", "ddaa" ], result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, -2 )
- def ReplaceChunk_MultipleLinesToSameMultipleLines_test():
- result_buffer = [ "aAa", "aBa", "aCa", "aDe" ]
- start, end = _BuildLocations( 2, 2, 3, 2 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'Eb\nbF',
- 0, 0, result_buffer )
- expected_buffer = [ "aAa", "aEb", "bFCa", "aDe" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, 1 )
- def ReplaceChunk_MultipleLinesToMoreMultipleLines_test():
- result_buffer = [ "aAa", "aBa", "aCa", "aDe" ]
- start, end = _BuildLocations( 2, 2, 3, 2 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
- end,
- 'Eb\nbFb\nbG',
- 0,
- 0,
- result_buffer )
- expected_buffer = [ "aAa", "aEb", "bFb", "bGCa", "aDe" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, 1 )
- eq_( char_offset, 1 )
- def ReplaceChunk_MultipleLinesToLessMultipleLines_test():
- result_buffer = [ "aAa", "aBa", "aCa", "aDe" ]
- start, end = _BuildLocations( 1, 2, 3, 2 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'Eb\nbF',
- 0, 0, result_buffer )
- expected_buffer = [ "aEb", "bFCa", "aDe" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, -1 )
- eq_( char_offset, 1 )
- def ReplaceChunk_MultipleLinesToEvenLessMultipleLines_test():
- result_buffer = [ "aAa", "aBa", "aCa", "aDe" ]
- start, end = _BuildLocations( 1, 2, 4, 2 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'Eb\nbF',
- 0, 0, result_buffer )
- expected_buffer = [ "aEb", "bFDe" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, -2 )
- eq_( char_offset, 1 )
- def ReplaceChunk_SpanBufferEdge_test():
- result_buffer = [ "aAa", "aBa", "aCa" ]
- start, end = _BuildLocations( 1, 1, 1, 3 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'bDb',
- 0, 0, result_buffer )
- expected_buffer = [ "bDba", "aBa", "aCa" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, 1 )
- def ReplaceChunk_DeleteTextInLine_test():
- result_buffer = [ "aAa", "aBa", "aCa" ]
- start, end = _BuildLocations( 2, 2, 2, 3 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, '',
- 0, 0, result_buffer )
- expected_buffer = [ "aAa", "aa", "aCa" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, -1 )
- def ReplaceChunk_AddTextInLine_test():
- result_buffer = [ "aAa", "aBa", "aCa" ]
- start, end = _BuildLocations( 2, 2, 2, 2 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'bDb',
- 0, 0, result_buffer )
- expected_buffer = [ "aAa", "abDbBa", "aCa" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, 3 )
- def ReplaceChunk_ReplaceTextInLine_test():
- result_buffer = [ "aAa", "aBa", "aCa" ]
- start, end = _BuildLocations( 2, 2, 2, 3 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'bDb',
- 0, 0, result_buffer )
- expected_buffer = [ "aAa", "abDba", "aCa" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, 2 )
- def ReplaceChunk_SingleLineOffsetWorks_test():
- result_buffer = [ "aAa", "aBa", "aCa" ]
- start, end = _BuildLocations( 1, 1, 1, 2 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'bDb',
- 1, 1, result_buffer )
- expected_buffer = [ "aAa", "abDba", "aCa" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, 0 )
- eq_( char_offset, 2 )
- def ReplaceChunk_SingleLineToMultipleLinesOffsetWorks_test():
- result_buffer = [ "aAa", "aBa", "aCa" ]
- start, end = _BuildLocations( 1, 1, 1, 2 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'Db\nE',
- 1, 1, result_buffer )
- expected_buffer = [ "aAa", "aDb", "Ea", "aCa" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, 1 )
- eq_( char_offset, -1 )
- def ReplaceChunk_MultipleLinesToSingleLineOffsetWorks_test():
- result_buffer = [ "aAa", "aBa", "aCa" ]
- start, end = _BuildLocations( 1, 1, 2, 2 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start, end, 'bDb',
- 1, 1, result_buffer )
- expected_buffer = [ "aAa", "abDbCa" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, -1 )
- eq_( char_offset, 3 )
- def ReplaceChunk_MultipleLineOffsetWorks_test():
- result_buffer = [ "aAa", "aBa", "aCa" ]
- start, end = _BuildLocations( 3, 1, 4, 3 )
- ( line_offset, char_offset ) = vimsupport.ReplaceChunk( start,
- end,
- 'bDb\nbEb\nbFb',
- -1,
- 1,
- result_buffer )
- expected_buffer = [ "aAa", "abDb", "bEb", "bFba" ]
- eq_( expected_buffer, result_buffer )
- eq_( line_offset, 1 )
- eq_( char_offset, 1 )
- 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,
- }
- def ReplaceChunksList_SortedChunks_test():
- chunks = [
- _BuildChunk( 1, 4, 1, 4, '('),
- _BuildChunk( 1, 11, 1, 11, ')' )
- ]
- result_buffer = [ "CT<10 >> 2> ct" ]
- vimsupport.ReplaceChunksList( chunks, result_buffer )
- expected_buffer = [ "CT<(10 >> 2)> ct" ]
- eq_( expected_buffer, result_buffer )
- def ReplaceChunksList_UnsortedChunks_test():
- chunks = [
- _BuildChunk( 1, 11, 1, 11, ')'),
- _BuildChunk( 1, 4, 1, 4, '(' )
- ]
- result_buffer = [ "CT<10 >> 2> ct" ]
- vimsupport.ReplaceChunksList( chunks, result_buffer )
- expected_buffer = [ "CT<(10 >> 2)> ct" ]
- eq_( expected_buffer, result_buffer )
- def _BuildChunk( start_line, start_column, end_line, end_column,
- replacement_text ):
- return {
- 'range': {
- 'start': {
- 'line_num': start_line,
- 'column_num': start_column,
- },
- 'end': {
- 'line_num': end_line,
- 'column_num': end_column,
- },
- },
- 'replacement_text': replacement_text
- }
- def _Mock_tempname( arg ):
- if arg == 'tempname()':
- return '_TEMP_FILE_'
- raise ValueError( 'Unexpected evaluation: ' + arg )
- @patch( 'vim.eval', side_effect=_Mock_tempname )
- @patch( 'vim.command' )
- @patch( 'vim.current' )
- def WriteToPreviewWindow_test( vim_current, vim_command, vim_eval ):
- vim_current.window.options.__getitem__ = MagicMock( return_value = True )
- vimsupport.WriteToPreviewWindow( "test" )
- vim_command.assert_has_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' ] )
- vim_current.buffer.options.__setitem__.assert_has_calls( [
- call( 'buftype', 'nofile' ),
- call( 'swapfile', False ),
- call( 'modifiable', False ),
- call( 'modified', False ),
- call( 'readonly', True ),
- ], any_order = True )
- @patch( 'vim.eval', side_effect=_Mock_tempname )
- @patch( 'vim.current' )
- def WriteToPreviewWindow_MultiLine_test( vim_current, vim_eval ):
- 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=_Mock_tempname )
- @patch( 'vim.command' )
- @patch( 'vim.current' )
- def WriteToPreviewWindow_JumpFail_test( vim_current, vim_command, vim_eval ):
- vim_current.window.options.__getitem__ = MagicMock( return_value = False )
- vimsupport.WriteToPreviewWindow( "test" )
- vim_command.assert_has_calls( [
- call( 'silent! pclose!' ),
- call( 'silent! pedit! _TEMP_FILE_' ),
- call( 'silent! wincmd P' ),
- call( "echom 'test'" ),
- ] )
- vim_current.buffer.__setitem__.assert_not_called()
- vim_current.buffer.options.__setitem__.assert_not_called()
- @patch( 'vim.eval', side_effect=_Mock_tempname )
- @patch( 'vim.command' )
- @patch( 'vim.current' )
- def WriteToPreviewWindow_JumpFail_MultiLine_test( vim_current,
- vim_command,
- vim_eval ):
- vim_current.window.options.__getitem__ = MagicMock( return_value = False )
- vimsupport.WriteToPreviewWindow( "test\ntest2" )
- vim_command.assert_has_calls( [
- call( 'silent! pclose!' ),
- call( 'silent! pedit! _TEMP_FILE_' ),
- call( 'silent! wincmd P' ),
- call( "echom 'test'" ),
- call( "echom 'test2'" ),
- ] )
- vim_current.buffer.__setitem__.assert_not_called()
- vim_current.buffer.options.__setitem__.assert_not_called()
|