diff --git a/tests/test_single_document.py b/tests/test_single_document.py index f54ce92d5..4ac3b4255 100644 --- a/tests/test_single_document.py +++ b/tests/test_single_document.py @@ -1,7 +1,14 @@ +from copy import deepcopy +from LSP.plugin import apply_text_edits, Request +from LSP.plugin.core.protocol import UINT_MAX from LSP.plugin.core.url import filename_to_uri +from LSP.plugin.core.views import entire_content +from LSP.plugin.hover import _test_contents from setup import TextDocumentTestCase +from setup import TIMEOUT_TIME from setup import YieldPromise import os +import sublime try: @@ -52,6 +59,25 @@ def test_did_open(self) -> None: # -> "shutdown" -> client shut down pass + def test_out_of_bounds_column_for_text_document_edit(self) -> None: + self.insert_characters("a\nb\nc\n") + apply_text_edits(self.view, [ + { + 'newText': 'hello there', + 'range': { + 'start': { + 'line': 1, + 'character': 0, + }, + 'end': { + 'line': 1, + 'character': 10000, + } + } + }, + ]) + self.assertEqual(entire_content(self.view), "a\nhello there\nc\n") + def test_did_close(self) -> 'Generator': self.assertTrue(self.view) self.assertTrue(self.view.is_valid()) @@ -82,3 +108,313 @@ def test_did_change(self) -> 'Generator': 'uri': filename_to_uri(TEST_FILE_PATH) } }) + + def test_sends_save_with_purge(self) -> 'Generator': + assert self.view + self.view.settings().set("lsp_format_on_save", False) + self.insert_characters("A") + self.view.run_command("lsp_save", {'async': True}) + yield from self.await_message("textDocument/didChange") + yield from self.await_message("textDocument/didSave") + yield from self.await_clear_view_and_save() + + def test_formats_on_save(self) -> 'Generator': + assert self.view + self.view.settings().set("lsp_format_on_save", True) + self.insert_characters("A") + yield from self.await_message("textDocument/didChange") + self.set_response('textDocument/formatting', [{ + 'newText': "BBB", + 'range': { + 'start': {'line': 0, 'character': 0}, + 'end': {'line': 0, 'character': 1} + } + }]) + self.view.run_command("lsp_save", {'async': True}) + yield from self.await_message("textDocument/formatting") + yield from self.await_message("textDocument/didChange") + yield from self.await_message("textDocument/didSave") + text = self.view.substr(sublime.Region(0, self.view.size())) + self.assertEquals("BBB", text) + yield from self.await_clear_view_and_save() + + def test_hover_info(self) -> 'Generator': + assert self.view + self.set_response('textDocument/hover', {"contents": "greeting"}) + self.view.run_command('insert', {"characters": "Hello Wrld"}) + self.assertFalse(self.view.is_popup_visible()) + self.view.run_command('lsp_hover', {'point': 3}) + yield lambda: self.view.is_popup_visible() + last_content = _test_contents[-1] + self.assertTrue("greeting" in last_content) + + def test_remove_line_and_then_insert_at_that_line_at_end(self) -> 'Generator': + original = ( + 'a\n' + 'b\n' + 'c' + ) + file_changes = [ + ((2, 0), (3, 0), ''), # out-of-bounds end position, but this is fine + ((3, 0), (3, 0), 'c\n') # out-of-bounds start and end, this line doesn't exist + ] + expected = ( + 'a\n' + 'b\n' + 'c\n' + ) + # Old behavior: + # 1) first we end up with ('a\n', 'b\n', 'cc\n') + # 2) then we end up with ('a\n', 'b\n', '') + # New behavior: + # 1) line index 3 is "created" ('a\n', 'b\n', 'c\n', c\n')) + # 2) deletes line index 2. + yield from self.__run_formatting_test(original, expected, file_changes) + + def test_apply_formatting(self) -> 'Generator': + original = ( + '\n' + '\n' + '\n' + '\n' + ) + file_changes = [ + ((0, 28), (1, 0), ''), # delete first \n + ((1, 0), (1, 15), ''), # delete second line (but not the \n) + ((2, 10), (2, 10), '\n '), # insert after