def test_hover_integration( language_server_initialized: IRobocorpLanguageServerClient, cases: CasesFixture): from robocorp_ls_core.workspace import Document client = language_server_initialized uri = "x/y/locators.json" txt = """ "Browser.Locator.01": { "screenshot": "iVBORw0KGgoAAAANSUhEUgAAACgAAAA" """ doc = Document("", txt) client.open_doc(uri, 1, txt) line, col = doc.get_last_line_col() ret = client.hover(uri, line, col) assert ret["result"] == { "contents": { "kind": "markdown", "value": "![Screenshot](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAA)", }, "range": { "start": { "line": 2, "character": 56 }, "end": { "line": 2, "character": 56 }, }, }
def test_variables_resolved_on_completion_integrated( language_server_tcp: ILanguageServerClient, workspace_dir, data_regression, cases ): from robocorp_ls_core.workspace import Document language_server = language_server_tcp language_server.initialize(workspace_dir, process_id=os.getpid()) uri = "untitled:Untitled-1" language_server.open_doc(uri, 1) contents = """*** Settings *** Library ${ROOT}/directory/my_library.py *** Keywords *** Some Keyword In Lib""" language_server.change_doc(uri, 2, contents) # Note: for libraries, if we found it, we keep it in memory (so, even though # we removed the entry, it'll still be accessible). language_server_tcp.settings( { "settings": { "robot": {"variables": {"ROOT": cases.get_path("case_same_basename")}} } } ) doc = Document("", source=contents) line, col = doc.get_last_line_col() completions = language_server.get_completions(uri, line, col) data_regression.check(completions)
def test_signature_help_integrated( language_server_io: ILanguageServerClient, ws_root_path, data_regression ): from robocorp_ls_core.workspace import Document language_server = language_server_io language_server.initialize(ws_root_path, process_id=os.getpid()) uri = "untitled:Untitled-1" txt = """ *** Test Cases *** Log It Log """ doc = Document("", txt) language_server.open_doc(uri, 1, txt) line, col = doc.get_last_line_col() ret = language_server.request_signature_help(uri, line, col) result = ret["result"] signatures = result["signatures"] # Don't check the signature documentation in the data regression so that the # test doesn't become brittle. docs = signatures[0].pop("documentation") assert "Log" in docs data_regression.check(result)
def test_rf_interactive_integrated_auto_import_completions( language_server_io: ILanguageServerClient, rf_interpreter_startup: _RfInterpreterInfo, data_regression, ): from robocorp_ls_core.workspace import Document from robotframework_ls_tests.fixtures import check_code_lens_data_regression # Check that we're able to get completions based on the current dir. from robotframework_ls.commands import ROBOT_INTERNAL_RFINTERACTIVE_COMPLETIONS from robocorp_ls_core.lsp import Position uri = rf_interpreter_startup.uri language_server = language_server_io code = "append to lis" doc = Document(uri, code) completions = language_server.execute_command( ROBOT_INTERNAL_RFINTERACTIVE_COMPLETIONS, [{ "interpreter_id": rf_interpreter_startup.interpreter_id, "code": code, "position": Position(*doc.get_last_line_col()).to_dict(), }], ) suggestions = completions["result"]["suggestions"] assert suggestions check_code_lens_data_regression(data_regression, suggestions)
def test_variables_completions_integrated( language_server_tcp: ILanguageServerClient, ws_root_path, data_regression ): from robocorp_ls_core.workspace import Document language_server = language_server_tcp language_server.initialize(ws_root_path, process_id=os.getpid()) uri = "untitled:Untitled-1" language_server.open_doc(uri, 1) contents = """ *** Variables *** ${NAME} Robot Framework ${VERSION} 2.0 ${ROBOT} ${NAME} ${VERSION} *** Test Cases *** List Variable Log ${NAME} Should Contain ${""" language_server.change_doc(uri, 2, contents) doc = Document("", source=contents) line, col = doc.get_last_line_col() completions = language_server.get_completions(uri, line, col) del completions["id"] data_regression.check(completions, "variable_completions") # Note: for libraries, if we found it, we keep it in memory (so, even though # we removed the entry, it'll still be accessible). language_server_tcp.settings({"settings": {"robot": {"variables": {"myvar1": 10}}}}) completions = language_server.get_completions(uri, line, col) labels = [x["label"] for x in completions["result"]] assert "${myvar1}" in labels
def test_formatting_basic(data_regression): from robotframework_ls.impl.formatting import ( robot_source_format, create_text_edit_from_diff, ) from robocorp_ls_core.workspace import Document contents = u""" ***Settings*** [Documentation]Some doc ***Test Case*** Check Call 1 2""" new_contents = robot_source_format(contents) assert u"*** Settings ***" in new_contents text_edits = create_text_edit_from_diff(contents, new_contents) doc = Document("", contents) doc.apply_text_edits(text_edits) data_regression.check(doc.source, basename="test_formatting_basic_formatted_doc") data_regression.check([x.to_dict() for x in text_edits], basename="test_formatting_basic_text_edits")
def test_keyword_completions_params_complete_existing_no_chars_with_empty_new_line_after( check): from robocorp_ls_core.workspace import Document base = CASE_TEMPLATE + " arg2=10 " doc = Document("", base) line, col = doc.get_last_line_col() check(base + "\n ", line_col=(line, col))
def _clear_caches(self): Document._clear_caches(self) self._symbols_cache = None self.get_ast.cache_clear(self) # noqa (clear the instance_cache). self.get_python_ast.cache_clear( self) # noqa (clear the instance_cache). self.get_yaml_contents.cache_clear( self) # noqa (clear the instance_cache).
def test_document_end_of_file_edit(): old = ["print 'a'\n", "print 'b'\n"] doc = Document("file:///uri", u"".join(old)) change = TextDocumentContentChangeEvent( Range(Position(2, 0), Position(2, 0)), 0, u"o") doc.apply_change(change) assert doc.get_internal_lines() == ("print 'a'\n", "print 'b'\n", "o")
def test_document_multiline_edit(): old = ["def hello(a, b):\n", " print a\n", " print b\n"] doc = Document("file:///uri", u"".join(old)) change = TextDocumentContentChangeEvent( Range(Position(1, 4), Position(2, 11)), 0, u"print a, b") doc.apply_change(change) assert doc.get_internal_lines() == ("def hello(a, b):\n", " print a, b\n")
def test_robotframework_integrated_completions(rf_configured_api, rf_root): from robocorp_ls_core import uris from robocorp_ls_core.workspace import Document api = rf_configured_api doc_uri = uris.from_fs_path( str(rf_root / "atest" / "robot" / "cli" / "dryrun" / "args.robot")) text = """*** Settings *** Suite Setup Run Tests --dryrun cli/dryrun/args.robot Resource atest_resource.robot *** Test Cases *** Valid positional args Check Test Case ${TESTNAME} Too few arguments Check Test Case ${TESTNAME} Too few arguments for UK Check Test Case ${TESTNAME} Too many arguments Check Test Case ${TESTNAME} Valid named args Check Test Case ${TESTNAME} Invalid named args Check Test Case ${TESTNAME} Ch""" api.m_text_document__did_open(textDocument={"uri": doc_uri, "text": text}) api.workspace.wait_for_check_done(10) doc = Document("") doc.source = text PRINT_TIMES = False if PRINT_TIMES: import time curtime = time.time() for i in range(5): line, col = doc.get_last_line_col() func = api.m_complete_all(doc_uri, line, col) assert len(func(monitor=NULL)) > 10 if PRINT_TIMES: print("Total %s: %.2fs" % (i, time.time() - curtime)) curtime = time.time()
def threaded_monaco_completions_from_code_full( self, prefix: str, full_code: str, position: PositionTypedDict, uri: str, indent: str, monitor: Optional[IMonitor] = None, ): from robotframework_ls.impl.robot_workspace import RobotDocument from robotframework_ls.impl.completion_context import CompletionContext from robocorp_ls_core.workspace import Document from robotframework_ls.impl import section_completions from robotframework_ls.impl import snippets_completions from robotframework_ls.server_api.monaco_conversions import ( convert_to_monaco_completion, ) from robotframework_ls.impl.completion_context import CompletionType d = Document(uri, prefix) last_line, _last_col = d.get_last_line_col() line = last_line + position["line"] col = position["character"] col += len(indent) document = RobotDocument(uri, full_code) completion_context = CompletionContext( document, line, col, config=self.config, monitor=monitor, workspace=self.workspace, ) completion_context.type = CompletionType.shell completions = self._complete_from_completion_context(completion_context) completions.extend(section_completions.complete(completion_context)) completions.extend(snippets_completions.complete(completion_context)) return { "suggestions": [ convert_to_monaco_completion( c, line_delta=last_line, col_delta=len(indent), uri=uri ) for c in completions ] }
def create_text_edit_from_diff(contents, new_contents): from difflib import SequenceMatcher from robocorp_ls_core.lsp import TextEdit from robocorp_ls_core.workspace import Document d = Document("", contents) s = SequenceMatcher(None, contents, new_contents) lst = [] for tag, i1, i2, j1, j2 in s.get_opcodes(): # print( # "%7s a[%d:%d] (%s) b[%d:%d] (%s)" # % (tag, i1, i2, contents[i1:i2], j1, j2, new_contents[j1:j2]) # ) if tag in ("replace", "insert"): lst.append(TextEdit(_create_range(d, i1, i2), new_contents[j1:j2])) elif tag == "delete": lst.append(TextEdit(_create_range(d, i1, i2), "")) elif tag == "equal": pass else: raise AssertionError("Unhandled: %s" % (tag, )) return lst
def test_hover_image_integration( language_server_initialized: IRobocorpLanguageServerClient, tmpdir): from robocorp_ls_core.workspace import Document from robocorp_code_tests.fixtures import IMAGE_IN_BASE64 import base64 from robocorp_ls_core import uris locators_json = tmpdir.join("locators.json") locators_json.write_text("", "utf-8") imgs_dir = tmpdir.join(".images") imgs_dir.mkdir() img1 = imgs_dir.join("img1.png") with img1.open("wb") as stream: stream.write(base64.b64decode(IMAGE_IN_BASE64)) client = language_server_initialized uri = uris.from_fs_path(str(locators_json)) txt = """ "Image.Locator.01": { "path": ".images/img1.png", "source": ".images/img1.png" """ doc = Document("", txt) client.open_doc(uri, 1, txt) line, col = doc.get_last_line_col() ret = client.hover(uri, line, col) result = ret["result"] value = result["contents"].pop("value") assert value.startswith("![Screenshot](file://") assert value.endswith("/.images/img1.png)") assert ret["result"] == { "contents": { "kind": "markdown", # "value": "![Screenshot](file:///c:/Users/fabio/AppData/Local/Temp/pytest-of-fabio/pytest-5202/test_hover_image_integration0/.images/img1.png)", }, "range": { "start": { "line": 3, "character": 37 }, "end": { "line": 3, "character": 37 }, }, }
def test_offset_to_line_col_1(): d = Document(uri="", source="my\nfo\nba") assert d.offset_to_line_col(0) == (0, 0) assert d.offset_to_line_col(1) == (0, 1) assert d.offset_to_line_col(2) == (0, 2) assert d.offset_to_line_col(3) == (1, 0) assert d.offset_to_line_col(4) == (1, 1) assert d.offset_to_line_col(5) == (1, 2) assert d.offset_to_line_col(6) == (2, 0) assert d.offset_to_line_col(7) == (2, 1) assert d.offset_to_line_col(8) == (2, 2) # Note: block below is out of bounds assert d.offset_to_line_col(9) == (2, 3) assert d.offset_to_line_col(10) == (2, 4)
def test_get_last_line_col(): d = Document(uri="", source="") assert d.get_last_line_col() == (0, 0) d.source = "my" assert d.get_last_line_col() == (0, 2) d.source = "my\n" assert d.get_last_line_col() == (1, 0)
def test_snippets_completions_integrated(language_server_tcp, ws_root_path, data_regression): from robocorp_ls_core.workspace import Document language_server = language_server_tcp language_server.initialize(ws_root_path, process_id=os.getpid()) uri = "untitled:Untitled-1" language_server.open_doc(uri, 1) contents = """ *** Test Cases *** List Variable for in""" language_server.change_doc(uri, 2, contents) doc = Document("", source=contents) line, col = doc.get_last_line_col() completions = language_server.get_completions(uri, line, col) del completions["id"] data_regression.check(completions, "snippet_completions")
def test_robotframework_integrated_go_to_def(rf_configured_api, rf_root): from robocorp_ls_core import uris from robocorp_ls_core.workspace import Document api = rf_configured_api doc_uri = uris.from_fs_path( str(rf_root / "atest" / "resources" / "foobar.robot")) text = """*** Settings *** Library TestCheckerLibrary""" api.m_text_document__did_open(textDocument={"uri": doc_uri, "text": text}) doc = Document("") doc.source = text line, col = doc.get_last_line_col() func = api.m_find_definition(doc_uri, line, col) found = func(monitor=NULL) assert len(found) == 1 found[0]["uri"].endswith("TestCheckerLibrary.py")
def test_word_from_cursor(): """ Return the position under the cursor (or last in line if past the end) """ doc = Document("uri", "doc1 doc2") assert doc.selection(0, 0).word_from_column == "doc1" assert doc.selection(0, 1).word_from_column == "oc1" assert doc.selection(0, 2).word_from_column == "c1" assert doc.selection(0, 3).word_from_column == "1" assert doc.selection(0, 4).word_from_column == "" assert doc.selection(0, 5).word_from_column == "doc2" assert doc.selection(0, 6).word_from_column == "oc2" assert doc.selection(0, 7).word_from_column == "c2" assert doc.selection(0, 8).word_from_column == "2" assert doc.selection(0, 9).word_from_column == "" assert doc.selection(0, 10).word_from_column == "" assert doc.selection(0, 11).word_from_column == ""
def test_hover_integrated(language_server_io: ILanguageServerClient, ws_root_path, data_regression): from robocorp_ls_core.workspace import Document from robocorp_ls_core.lsp import HoverTypedDict language_server = language_server_io language_server.initialize(ws_root_path, process_id=os.getpid()) uri = "untitled:Untitled-1" txt = """ *** Test Cases *** Log It Log """ doc = Document("", txt) language_server.open_doc(uri, 1, txt) line, col = doc.get_last_line_col() ret = language_server.request_hover(uri, line, col) result: HoverTypedDict = ret["result"] contents = result["contents"] assert "Log" in contents["value"] assert contents["kind"] == "markdown"
def test_rf_interactive_integrated_fs_completions( language_server_io: ILanguageServerClient, rf_interpreter_startup: _RfInterpreterInfo, data_regression, ): from robocorp_ls_core import uris from robocorp_ls_core.workspace import Document # Check that we're able to get completions based on the current dir. from robotframework_ls.commands import ROBOT_INTERNAL_RFINTERACTIVE_COMPLETIONS from robocorp_ls_core.lsp import Position uri = rf_interpreter_startup.uri fs_path = uris.to_fs_path(uri) dirname = os.path.dirname(fs_path) with open(os.path.join(dirname, "my_lib_03.py"), "w") as stream: stream.write(""" def some_method(): pass """) language_server = language_server_io code = "*** Settings ***\nLibrary ./my_" doc = Document(uri, code) completions = language_server.execute_command( ROBOT_INTERNAL_RFINTERACTIVE_COMPLETIONS, [{ "interpreter_id": rf_interpreter_startup.interpreter_id, "code": code, "position": Position(*doc.get_last_line_col()).to_dict(), }], ) suggestions = completions["result"]["suggestions"] assert suggestions data_regression.check(suggestions)
def test_offset_to_line_col_2(): d = Document(uri="", source="\n\n\n") with pytest.raises(ValueError): assert d.offset_to_line_col(-1) assert d.offset_to_line_col(0) == (0, 0) assert d.offset_to_line_col(1) == (1, 0) assert d.offset_to_line_col(2) == (2, 0) # Note: block below is out of bounds assert d.offset_to_line_col(3) == (3, 0) assert d.offset_to_line_col(4) == (3, 1)
def __init__(self, uri, source=None, version=None, generate_ast=True): Document.__init__(self, uri, source=source, version=version) self._generate_ast = generate_ast self._ast = None self.symbols_cache = None
def test_document_source_unicode(): document_mem = Document(DOC_URI, u"my source") document_disk = Document(DOC_URI) assert isinstance(document_mem.source, type(document_disk.source))
def test_document_line_edit(): doc = Document("file:///uri", u"itshelloworld") change = TextDocumentContentChangeEvent( Range(Position(0, 3), Position(0, 8)), 0, u"goodbye") doc.apply_change(change) assert doc.source == u"itsgoodbyeworld"
def _clear_caches(self): Document._clear_caches(self) self._symbols_cache = None self.get_ast.cache_clear(self) # noqa (clear the instance_cache).
def test_document_empty_edit(): doc = Document("file:///uri", u"") change = TextDocumentContentChangeEvent( Range(Position(0, 0), Position(0, 0)), 0, u"f") doc.apply_change(change) assert doc.source == u"f"
def doc(): return Document(DOC_URI, DOC)
def test_get_document_range(): d = Document(uri="", source="aa\nbb\ncc") assert d.get_range(0, 0, 0, 1) == "a" assert d.get_range(0, 1, 0, 2) == "a" assert d.get_range(0, 2, 0, 3) == "" assert d.get_range(0, 1, 0, 3) == "a" assert d.get_range(0, 0, 0, 3) == "aa" assert d.get_range(1, 0, 1, 1) == "b" assert d.get_range(1, 1, 1, 2) == "b" assert d.get_range(1, 2, 1, 3) == "" assert d.get_range(1, 1, 1, 3) == "b" assert d.get_range(1, 0, 1, 3) == "bb" assert d.get_range(2, 0, 2, 1) == "c" assert d.get_range(2, 1, 2, 2) == "c" assert d.get_range(2, 2, 2, 3) == "" assert d.get_range(2, 1, 2, 3) == "c" assert d.get_range(2, 0, 2, 3) == "cc" assert d.get_range(3, 0, 3, 1) == "" assert d.get_range(3, 1, 3, 2) == "" assert d.get_range(3, 2, 3, 3) == "" assert d.get_range(3, 1, 3, 3) == "" assert d.get_range(3, 0, 3, 3) == "" assert d.get_range(0, 0, 1, 1) == "aa\nb" assert d.get_range(0, 0, 1, 2) == "aa\nbb" assert d.get_range(0, 0, 1, 3) == "aa\nbb\n" assert d.get_range(0, 0, 1, 4) == "aa\nbb\n" assert d.get_range(0, 0, 2, 1) == "aa\nbb\nc" assert d.get_range(0, 0, 2, 2) == "aa\nbb\ncc" assert d.get_range(0, 0, 3, 1) == "aa\nbb\ncc" assert d.get_range(0, 0, 4, 1) == "aa\nbb\ncc" assert d.get_range(0, 0, 4, 0) == "aa\nbb\ncc"
def test_get_line(): d = Document(uri="", source="") assert d.get_last_line() == "" d.source = "my\nfoo" assert d.get_line(0) == "my" assert d.get_last_line() == "foo" assert d.get_line_count() == 2 d.source = "my\nfoo\n" assert d.get_line(0) == "my" assert d.get_line(1) == "foo" assert d.get_line(2) == "" assert d.get_last_line() == "" assert list(d.iter_lines()) == ["my\n", "foo\n", ""] assert list(d.iter_lines(False)) == ["my", "foo", ""]