def test_find_definition_keywords(language_server, cases, tmpdir): from robotframework_ls import uris workspace_dir = str(tmpdir.join("workspace")) cases.copy_to("case2", workspace_dir) language_server.initialize(workspace_dir, process_id=os.getpid()) case2_robot = os.path.join(workspace_dir, "case2.robot") assert os.path.exists(case2_robot) uri = uris.from_fs_path(case2_robot) language_server.open_doc(uri, 1, text=None) ret = language_server.find_definitions(uri, 7, 6) result = ret["result"] assert len(result) == 1 check = next(iter(result)) assert check["uri"].endswith("case2.robot") assert check["range"] == { "start": { "line": 1, "character": 0 }, "end": { "line": 4, "character": 5 }, }
def initialize(self, root_path, msg_id=None, process_id=None): from robotframework_ls.uris import from_fs_path msg_id = msg_id if msg_id is not None else self.next_id() self.write( { "jsonrpc": "2.0", "id": msg_id, "method": "initialize", "params": { "processId": process_id, "rootPath": root_path, "rootUri": from_fs_path(root_path), "capabilities": { "workspace": { "applyEdit": True, "didChangeConfiguration": {"dynamicRegistration": True}, "didChangeWatchedFiles": {"dynamicRegistration": True}, "symbol": {"dynamicRegistration": True}, "executeCommand": {"dynamicRegistration": True}, }, "textDocument": { "synchronization": { "dynamicRegistration": True, "willSave": True, "willSaveWaitUntil": True, "didSave": True, }, "completion": { "dynamicRegistration": True, "completionItem": { "snippetSupport": True, "commitCharactersSupport": True, }, }, "hover": {"dynamicRegistration": True}, "signatureHelp": {"dynamicRegistration": True}, "definition": {"dynamicRegistration": True}, "references": {"dynamicRegistration": True}, "documentHighlight": {"dynamicRegistration": True}, "documentSymbol": {"dynamicRegistration": True}, "codeAction": {"dynamicRegistration": True}, "codeLens": {"dynamicRegistration": True}, "formatting": {"dynamicRegistration": True}, "rangeFormatting": {"dynamicRegistration": True}, "onTypeFormatting": {"dynamicRegistration": True}, "rename": {"dynamicRegistration": True}, "documentLink": {"dynamicRegistration": True}, }, }, "trace": "off", }, } ) msg = self.wait_for_message({"id": msg_id}) assert "capabilities" in msg["result"] return msg
def iter_imports_docs(self): from robotframework_ls import uris import os.path from robotframework_ls.impl import ast_utils ws = self._workspace # Get keywords from resources resource_imports = self.get_resource_imports() for resource_import in resource_imports: for token in resource_import.tokens: if token.type == token.NAME: parts = [] for v in ast_utils.tokenize_variables(token): if v.type == v.NAME: parts.append(str(v)) elif v.type == v.VARIABLE: # Resolve variable from config v = str(v) if v.startswith("${") and v.endswith("}"): v = v[2:-1] parts.append(self.convert_robot_variable(v)) else: log.info("Cannot resolve variable: %s", v) resource_path = "".join(parts) if not os.path.isabs(resource_path): # It's a relative resource, resolve its location based on the # current file. resource_path = os.path.join( os.path.dirname(self.doc.path), resource_path) if not os.path.isfile(resource_path): log.info("Resource not found: %s", resource_path) continue doc_uri = uris.from_fs_path(resource_path) resource_doc = ws.get_document(doc_uri, create=False) if resource_doc is None: resource_doc = ws.create_untracked_document(doc_uri) yield resource_doc
def m_find_definition(self, doc_uri, line, col): from robotframework_ls.impl.find_definition import find_definition import os.path from robotframework_ls.lsp import Location, Range from robotframework_ls import uris completion_context = self._create_completion_context(doc_uri, line, col) if completion_context is None: return None definitions = find_definition(completion_context) ret = [] for definition in definitions: if not definition.source: log.info("Found definition with empty source (%s).", definition) continue if not os.path.exists(definition.source): log.info( "Found definition: %s (but source does not exist).", definition ) continue lineno = definition.lineno if lineno is None or lineno < 0: lineno = 0 end_lineno = definition.end_lineno if end_lineno is None or end_lineno < 0: end_lineno = 0 col_offset = definition.col_offset end_col_offset = definition.end_col_offset ret.append( Location( uris.from_fs_path(definition.source), Range((lineno, col_offset), (end_lineno, end_col_offset)), ).to_dict() ) return ret
def test_libspec_manager_caches(libspec_manager, tmpdir): from robotframework_ls import uris from os.path import os from robotframework_ls_tests.fixtures import LIBSPEC_1 from robotframework_ls_tests.fixtures import wait_for_condition from robotframework_ls_tests.fixtures import LIBSPEC_2 from robotframework_ls_tests.fixtures import LIBSPEC_2_A import time ws_dir = str(tmpdir.join("workspace_dir_a")) os.mkdir(ws_dir) with open(os.path.join(ws_dir, "my.libspec"), "w") as stream: stream.write(LIBSPEC_1) libspec_manager.add_workspace_folder(uris.from_fs_path(ws_dir)) assert libspec_manager.get_library_info("case1_library", create=False) is not None libspec_manager.remove_workspace_folder(uris.from_fs_path(ws_dir)) library_info = libspec_manager.get_library_info("case1_library", create=False) if library_info is not None: raise AssertionError("Expected: %s to be None after removing %s" % (library_info, uris.from_fs_path(ws_dir))) libspec_manager.add_workspace_folder(uris.from_fs_path(ws_dir)) assert libspec_manager.get_library_info("case1_library", create=False) is not None # Give a timeout so that the next write will have at least 1 second # difference (1s is the minimum for poll to work). time.sleep(1.1) with open(os.path.join(ws_dir, "my2.libspec"), "w") as stream: stream.write(LIBSPEC_2) def check_spec_found(): library_info = libspec_manager.get_library_info("case2_library", create=False) return library_info is not None # Updating is done in a thread. wait_for_condition(check_spec_found, sleep=1 / 5.0) library_info = libspec_manager.get_library_info("case2_library", create=False) assert set(x.name for x in library_info.keywords) == set( ["Case 2 Verify Another Model", "Case 2 Verify Model"]) # Give a timeout so that the next write will have at least 1 second # difference (1s is the minimum for poll to work). time.sleep(1) with open(os.path.join(ws_dir, "my2.libspec"), "w") as stream: stream.write(LIBSPEC_2_A) def check_spec_2_a(): library_info = libspec_manager.get_library_info("case2_library", create=False) if library_info: return set(x.name for x in library_info.keywords) == set( ["Case 2 A Verify Another Model", "Case 2 A Verify Model"]) # Updating is done in a thread. wait_for_condition(check_spec_2_a, sleep=1 / 5.0)
# distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from robotframework_ls.workspace import Document from robotframework_ls.lsp import TextDocumentContentChangeEvent, Position, Range from robotframework_ls import uris import pytest import os.path DOC = """document for testing """ DOC_URI = uris.from_fs_path(os.path.abspath(__file__)) @pytest.fixture def doc(): return Document(DOC_URI, DOC) 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 test_win_from_fs_path(path, uri): assert uris.from_fs_path(path) == uri
def get_doc(self, root_relative_path, create=True): from robotframework_ls import uris path = os.path.join(self._ws.root_path, root_relative_path) uri = uris.from_fs_path(path) return self.ws.get_document(uri, create=create)
def set_root(self, relative_path, **kwargs): from robotframework_ls import uris from robotframework_ls.impl.robot_workspace import RobotWorkspace path = self._cases.get_path(relative_path) self._ws = RobotWorkspace(uris.from_fs_path(path), **kwargs)