def test_keyword_completions_format(workspace, libspec_manager): from robotframework_ls.impl import keyword_completions from robotframework_ls.impl.completion_context import CompletionContext from robotframework_ls.robot_config import RobotConfig from robotframework_ls.impl.robot_lsp_constants import ( OPTION_ROBOT_COMPLETION_KEYWORDS_FORMAT, OPTION_ROBOT_COMPLETION_KEYWORDS_FORMAT_FIRST_UPPER, ) workspace.set_root("case1", libspec_manager=libspec_manager) doc = workspace.get_doc("case1.robot") doc.source = doc.source + "\n should be" config = RobotConfig() config.update({ OPTION_ROBOT_COMPLETION_KEYWORDS_FORMAT: OPTION_ROBOT_COMPLETION_KEYWORDS_FORMAT_FIRST_UPPER }) assert (config.get_setting( OPTION_ROBOT_COMPLETION_KEYWORDS_FORMAT, str, "") == OPTION_ROBOT_COMPLETION_KEYWORDS_FORMAT_FIRST_UPPER) completions = keyword_completions.complete( CompletionContext(doc, workspace=workspace.ws, config=config)) assert sorted([comp["label"] for comp in completions]) == [ "Length should be", "Should be empty", "Should be equal", "Should be equal as integers", "Should be equal as numbers", "Should be equal as strings", "Should be true", ]
def test_config_variable_resolution(monkeypatch): from robotframework_ls.impl.robot_lsp_constants import ( OPTION_ROBOT_PYTHON_EXECUTABLE, ) from robotframework_ls.robot_config import RobotConfig from robotframework_ls.impl.robot_lsp_constants import OPTION_ROBOT_VARIABLES from robotframework_ls.impl.robot_lsp_constants import OPTION_ROBOT_PYTHONPATH monkeypatch.setenv("FOO", "22") config = RobotConfig() settings = { "robot": { "python": {"executable": "${env.FOO}"}, "variables": {"VAR1": "~/foo${env.FOO}/${env.FOO}"}, "pythonpath": ["~/foo${env.FOO}/${env.FOO}", "${workspace}/a"], } } config.update(settings) assert config.get_setting(OPTION_ROBOT_PYTHON_EXECUTABLE, str) == "22" assert config.get_setting(OPTION_ROBOT_VARIABLES, dict) == { "VAR1": os.path.expanduser("~") + "/foo22/22" } assert config.get_setting(OPTION_ROBOT_PYTHONPATH, list) == [ os.path.expanduser("~") + "/foo22/22", "${workspace}/a", ] config.set_workspace_dir("workspacepath") assert config.get_setting(OPTION_ROBOT_PYTHONPATH, list) == [ os.path.expanduser("~") + "/foo22/22", "workspacepath/a", ]
def test_keyword_completions_from_resource_files(data_regression, workspace, tmpdir, cases, libspec_manager): from robotframework_ls.impl import keyword_completions from robotframework_ls.impl.completion_context import CompletionContext from robotframework_ls.impl.robot_lsp_constants import OPTION_ROBOT_VARIABLES from robotframework_ls.robot_config import RobotConfig config = RobotConfig() config.update( {"robot": { "variables": { "ext_folder": cases.get_path("ext") } }}) assert config.get_setting(OPTION_ROBOT_VARIABLES, dict, {}) == { "ext_folder": cases.get_path("ext") } workspace.set_root(cases.get_path("case3"), libspec_manager=libspec_manager) doc = workspace.get_doc("case3.robot") doc.source = doc.source + "\n equal redef" completions = keyword_completions.complete( CompletionContext(doc, workspace=workspace.ws, config=config)) data_regression.check(completions, basename="keyword_completions_from_resource_files")
def test_resource_completions_resolve_var(data_regression, workspace, cases, libspec_manager, workspace_dir): from robotframework_ls.impl import filesystem_section_completions from robotframework_ls.impl.completion_context import CompletionContext from robotframework_ls.impl.robot_lsp_constants import OPTION_ROBOT_VARIABLES from robotframework_ls.robot_config import RobotConfig cases.copy_to("case4", workspace_dir) config = RobotConfig() config.update( {"robot": { "variables": { "ext_folder": cases.get_path("ext") } }}) assert config.get_setting(OPTION_ROBOT_VARIABLES, dict, {}) == { "ext_folder": cases.get_path("ext") } workspace.set_root(workspace_dir, libspec_manager=libspec_manager) doc = workspace.get_doc("case4.robot") doc.source = """*** Settings *** Resource ${ext_folder}/""" completions = filesystem_section_completions.complete( CompletionContext(doc, workspace=workspace.ws, config=config)) data_regression.check(completions)
def test_find_definition_keyword_resource_in_pythonpath( workspace, libspec_manager, cases): from robotframework_ls.impl.completion_context import CompletionContext from robotframework_ls.impl.find_definition import find_definition from robotframework_ls.robot_config import RobotConfig from robotframework_ls.impl.robot_lsp_constants import OPTION_ROBOT_PYTHONPATH case2_path = cases.get_path("case2") config = RobotConfig() config.update({"robot": {"pythonpath": [case2_path]}}) assert config.get_setting(OPTION_ROBOT_PYTHONPATH, list, []) == [case2_path] libspec_manager.config = config workspace.set_root("case1", libspec_manager=libspec_manager) doc = workspace.get_doc("case1.robot") doc.source = """ *** Settings *** Resource case2.robot""" completion_context = CompletionContext(doc, workspace=workspace.ws, config=config) definitions = find_definition(completion_context) assert len(definitions) == 1, "Failed to find definition" definition = next(iter(definitions)) assert definition.source.endswith("case2.robot") assert definition.lineno == 0
def test_keyword_completions_respect_pythonpath(workspace, cases, libspec_manager, data_regression): from robotframework_ls.impl import keyword_completions from robotframework_ls.impl.completion_context import CompletionContext from robotframework_ls.robot_config import RobotConfig from robotframework_ls.impl.robot_lsp_constants import OPTION_ROBOT_PYTHONPATH case4_path = cases.get_path("case4") # Note how we are accessing case4resource.txt while the workspace is set for case3. config = RobotConfig() config.update({"robot": {"pythonpath": [case4_path]}}) assert config.get_setting(OPTION_ROBOT_PYTHONPATH, list, []) == [case4_path] libspec_manager.config = config workspace.set_root(cases.get_path("case3"), libspec_manager=libspec_manager) doc = workspace.get_doc("case3.robot") doc.source = """*** Settings *** Resource case4resource.txt *** Test Cases *** Can use resource keywords [Documentation] Checks that we can have a resource ... including another resource. My Equal Redefined 2 2 Yet Another Equ""" completions = keyword_completions.complete( CompletionContext(doc, workspace=workspace.ws, config=config)) data_regression.check(completions)
def test_completion_not_duplicated(workspace, cases, libspec_manager, workspace_dir): from robocorp_ls_core.lsp import TextDocumentItem import os.path from robocorp_ls_core import uris from robotframework_ls.robot_config import RobotConfig from robotframework_ls.impl.collect_keywords import ( collect_keyword_name_to_keyword_found, ) from robotframework_ls.impl.protocols import IKeywordFound cases.copy_to("case_inner_keywords", workspace_dir) workspace.set_root(workspace_dir, libspec_manager=libspec_manager) config = RobotConfig() config.update({"robot.pythonpath": [workspace_dir]}) libspec_manager.config = config uri = uris.from_fs_path(os.path.join(workspace_dir, "inner", "case_inner.robot")) workspace.ws.put_document( TextDocumentItem( uri, text="""*** Settings *** Resource case_root.robot *** Keywords *** Check with keyword at inner [Arguments] ${arg1} ${arg2} Should Be Equal ${arg1} ${arg2} *** Test Cases *** Testing Completion Here Check with ke""", ) ) doc = workspace.ws.get_document(uri, accept_from_file=False) from robotframework_ls.impl.completion_context import CompletionContext from robotframework_ls.impl import auto_import_completions workspace.ws.wait_for_check_done(5) context = CompletionContext(doc, workspace=workspace.ws, config=config) keyword_name_to_keyword_found: Dict[ str, List[IKeywordFound] ] = collect_keyword_name_to_keyword_found(context) completions = auto_import_completions.complete( context, keyword_name_to_keyword_found ) # I.e.: all the related symbols are already imported and will be shown # in the regular completion. assert len(completions) == 0
def test_resource_does_not_exist(workspace, libspec_manager, data_regression): workspace.set_root("case4", libspec_manager=libspec_manager) doc = workspace.get_doc("case4.robot") doc.source = """*** Settings *** Library DoesNotExist Library . Library .. Library ../ Resource does_not_exist.txt Resource ${foo}/does_not_exist.txt Resource ../does_not_exist.txt Resource . Resource .. Resource ../ Resource ../../does_not_exist.txt Resource case4resource.txt *** Test Cases *** Test case4resource3.Yet Another Equal Redefined""" from robotframework_ls.robot_config import RobotConfig config = RobotConfig() _collect_errors(workspace, doc, data_regression, basename="test_resource_does_not_exist", config=config)
def test_casing_on_filename(workspace, libspec_manager, data_regression): from robocorp_ls_core.protocols import IDocument from pathlib import Path # i.e.: Importing a python library with capital letters fails #143 workspace.set_root("case4", libspec_manager=libspec_manager) doc: IDocument = workspace.get_doc("case4.robot") p = Path(doc.path) (p.parent / "myPythonKeywords.py").write_text( """ class myPythonKeywords(object): ROBOT_LIBRARY_VERSION = 1.0 def __init__(self): pass def Uppercase_Keyword (self): return "Uppercase does not work" """ ) doc.source = """*** Settings *** Library myPythonKeywords.py *** Test Cases *** Test Uppercase Keyword""" from robotframework_ls.robot_config import RobotConfig config = RobotConfig() # Note: we don't give errors if we can't resolve a resource. _collect_errors(workspace, doc, data_regression, basename="no_error", config=config)
def test_keyword_completions_directory_separator(workspace, libspec_manager, use_config, separator): from robotframework_ls.impl import keyword_completions from robotframework_ls.impl.completion_context import CompletionContext from robotframework_ls.robot_config import RobotConfig import sys if sys.platform != "win32" and separator == "\\": return workspace.set_root("case_inner_keywords", libspec_manager=libspec_manager) doc = workspace.get_doc("case_root.robot") doc.source = f""" *** Settings *** Resource inner{separator}case_inner.robot *** Test Cases *** Testing Completion Here Check with ke""" if use_config: config = RobotConfig() else: config = None completions = keyword_completions.complete( CompletionContext(doc, workspace=workspace.ws, config=config)) assert sorted([comp["label"] for comp in completions ]) == ["Check with keyword at inner"]
def test_keyword_completions_resource_does_not_exist(workspace, libspec_manager, data_regression): from robotframework_ls.robot_config import RobotConfig from robotframework_ls.impl import keyword_completions from robotframework_ls.impl.completion_context import CompletionContext workspace.set_root("case4", libspec_manager=libspec_manager) doc = workspace.get_doc("case4.robot") doc.source = """*** Settings *** Library DoesNotExist Library . Library .. Library ../ Resource does_not_exist.txt Resource ${foo}/does_not_exist.txt Resource ../does_not_exist.txt Resource . Resource .. Resource ../ Resource ../../does_not_exist.txt Resource case4resource.txt *** Test Cases *** Test case4resource3.""" config = RobotConfig() completions = keyword_completions.complete( CompletionContext(doc, workspace=workspace.ws, config=config)) data_regression.check(completions)
def test_code_analysis_lib_with_params( workspace, libspec_manager, cases, data_regression ): from robotframework_ls.robot_config import RobotConfig from robotframework_ls.impl.robot_lsp_constants import OPTION_ROBOT_PYTHONPATH workspace.set_root("case_params_on_lib", libspec_manager=libspec_manager) caseroot = cases.get_path("case_params_on_lib") config = RobotConfig() config.update({"robot": {"pythonpath": [caseroot]}}) assert config.get_setting(OPTION_ROBOT_PYTHONPATH, list, []) == [caseroot] libspec_manager.config = config doc = workspace.get_doc("case_params_on_lib.robot") _collect_errors(workspace, doc, data_regression, basename="no_error", config=config)
def test_simple(workspace, libspec_manager, cases): from robotframework_ls.impl import keyword_completions from robotframework_ls.impl.completion_context import CompletionContext from robotframework_ls.robot_config import RobotConfig from robotframework_ls.impl.robot_lsp_constants import OPTION_ROBOT_PYTHONPATH workspace.set_root("case_params_on_lib", libspec_manager=libspec_manager) caseroot = cases.get_path("case_params_on_lib") config = RobotConfig() config.update({"robot": {"pythonpath": [caseroot]}}) assert config.get_setting(OPTION_ROBOT_PYTHONPATH, list, []) == [caseroot] libspec_manager.config = config doc = workspace.get_doc("case_params_on_lib.robot") completions = keyword_completions.complete( CompletionContext(doc, workspace=workspace.ws)) assert sorted([comp["label"] for comp in completions]) == ["Some Method"]
def test_completion_with_auto_import_keyword_format(workspace, cases, libspec_manager, workspace_dir): from robotframework_ls.impl.completion_context import CompletionContext from robotframework_ls.impl import auto_import_completions from robotframework_ls.robot_config import RobotConfig from robotframework_ls.impl.robot_lsp_constants import ( OPTION_ROBOT_COMPLETION_KEYWORDS_FORMAT, ) cases.copy_to("case1", workspace_dir) config = RobotConfig() # Check that although the options are presented with case, the comparison # internally is case-insensitive. config.update({OPTION_ROBOT_COMPLETION_KEYWORDS_FORMAT: "AlL lowEr"}) workspace.set_root(workspace_dir, libspec_manager=libspec_manager) doc = workspace.get_doc("case1.robot") doc.source = """ *** Settings *** Library case1_library *** Test Cases *** User can call library Copy Diction""" completions = auto_import_completions.complete( CompletionContext(doc, workspace=workspace.ws, config=config), {}) assert len(completions) == 1 apply_completion(doc, completions[0]) assert (doc.source == """ *** Settings *** Library case1_library Library Collections *** Test Cases *** User can call library copy dictionary""")
def test_find_definition_in_pythonpath(workspace, libspec_manager, cases): from robotframework_ls.impl.completion_context import CompletionContext from robotframework_ls.impl.find_definition import find_definition from robotframework_ls.robot_config import RobotConfig from robotframework_ls.impl.robot_lsp_constants import OPTION_ROBOT_PYTHONPATH add_to_pythonpath = cases.get_path("case_search_pythonpath/libraries") config = RobotConfig() config.update({"robot": {"pythonpath": [add_to_pythonpath]}}) assert config.get_setting(OPTION_ROBOT_PYTHONPATH, list, []) == [add_to_pythonpath] libspec_manager.config = config workspace.set_root("case_search_pythonpath", libspec_manager=libspec_manager) doc1 = workspace.get_doc("case_search_pythonpath.robot") completion_context = CompletionContext(doc1, workspace=workspace.ws, config=config) def1 = find_definition(completion_context) assert len(def1) == 1 assert def1[0].source.endswith("lib_in_pythonpath.py")
def __init__(self, log_extension, language_server_ref): self._main_thread = threading.current_thread() from robotframework_ls.robot_config import RobotConfig self._used_python_executable = None self._used_environ = None self._server_process = None self._robotframework_api_client: Optional[ IRobotFrameworkApiClient] = None # We have a version of the config with the settings passed overridden # by the settings of a given (customized) interpreter. self._config: IConfig = RobotConfig() self.workspace = None self._initializing = False self._log_extension = log_extension self._language_server_ref = language_server_ref self._interpreter_info: Optional[IInterpreterInfo] = None
def test_section_completions(data_regression): from robotframework_ls.impl import section_completions from robotframework_ls.impl.completion_context import CompletionContext from robotframework_ls.impl.robot_workspace import RobotDocument from robotframework_ls.robot_config import RobotConfig config = RobotConfig() config.update({"robot": {"completions": {"section_headers": {"form": "both"}}}}) doc = RobotDocument("unused", source="""**""") completions = section_completions.complete(CompletionContext(doc, config=config)) data_regression.check(completions, basename="header_completions_all") doc = RobotDocument("unused", source="""**settin""") completions = section_completions.complete(CompletionContext(doc, config=config)) data_regression.check(completions, basename="header_completions_filter_settings") config.update({}) doc = RobotDocument("unused", source="""**""") completions = section_completions.complete(CompletionContext(doc, config=config)) data_regression.check(completions, basename="header_completions_all_plural")
def config(): from robotframework_ls.robot_config import RobotConfig return RobotConfig()
def _create_config(self) -> IConfig: from robotframework_ls.robot_config import RobotConfig return RobotConfig()
def test_config(): from robotframework_ls.impl.robot_lsp_constants import ( OPTION_ROBOT_PYTHON_EXECUTABLE, ) from robotframework_ls.robot_config import RobotConfig from robotframework_ls.impl.robot_lsp_constants import ( OPTION_ROBOT_LANGUAGE_SERVER_TCP_PORT, ) config = RobotConfig() settings = { "robot": { "language-server": { "tcp-port": 1456, "args": ["-vv", "--log-file=~/robotframework_ls.log"], }, "python": { "executable": "foobar", "value": "10", "value_float": "10.5" }, } } config.update(settings) assert config.get_setting(OPTION_ROBOT_PYTHON_EXECUTABLE, str) == "foobar" assert config.get_setting(OPTION_ROBOT_LANGUAGE_SERVER_TCP_PORT, int) == 1456 # i.e.: convert to type when possible assert config.get_setting("robot.python.value", int) == 10 assert config.get_setting("robot.python.value_float", float) == 10.5 with pytest.raises(KeyError): config.get_setting("robot.python.value_float", int) with pytest.raises(KeyError): assert config.get_setting("robot.not_there", int)