diff --git a/test-sourcekit-lsp/test-sourcekit-lsp.py b/test-sourcekit-lsp/test-sourcekit-lsp.py index 92ca2c5..969388d 100644 --- a/test-sourcekit-lsp/test-sourcekit-lsp.py +++ b/test-sourcekit-lsp/test-sourcekit-lsp.py @@ -44,21 +44,11 @@ def send_data(self, dict: Dict[str, object]): self.process.stdin.write(data) self.process.stdin.flush() - def send_request(self, method: str, params: Dict[str, object]) -> str: + def read_message_from_lsp_server(self) -> str: """ - Send a request of the given method and parameters to the LSP server and wait for the response. + Read a single message sent from the LSP server to the client. + This can be a request reply, notification or request sent from the server to the client. """ - self.request_id += 1 - - self.send_data( - { - "jsonrpc": "2.0", - "id": self.request_id, - "method": method, - "params": params, - } - ) - assert self.process.stdout # Read Content-Length: 123\r\n # Note: Even though the Content-Length header ends with \r\n, `readline` returns it with a single \n. @@ -71,11 +61,44 @@ def send_request(self, method: str, params: Dict[str, object]) -> str: assert empty_line == "\n", f"Expected empty line, got '{empty_line}'" # Read the actual response - response = self.process.stdout.read(int(match.group(1))) + return self.process.stdout.read(int(match.group(1))) + + def read_request_reply_from_lsp_server(self, request_id: int) -> str: + """ + Read all messages sent from the LSP server until we see a request reply. + Assert that this request reply was for the given request_id and return it. + """ + message = self.read_message_from_lsp_server() + message_obj = json.loads(message) + if "result" not in message_obj: + # We received a message that wasn't the request reply. + # Log it, ignore it and wait for the next message. + print("Received message") + print(message) + return self.read_request_reply_from_lsp_server(request_id) + # We always wait for a request reply before sending the next request. + # If we received a request reply, it should thus have the request ID of the last request that we sent. assert ( - f'"id":{self.request_id}' in response - ), f"Expected response for request {self.request_id}, got '{response}'" - return response + message_obj["id"] == self.request_id + ), f"Expected response for request {self.request_id}, got '{message}'" + return message + + def send_request(self, method: str, params: Dict[str, object]) -> str: + """ + Send a request of the given method and parameters to the LSP server and wait for the response. + """ + self.request_id += 1 + + self.send_data( + { + "jsonrpc": "2.0", + "id": self.request_id, + "method": method, + "params": params, + } + ) + + return self.read_request_reply_from_lsp_server(self.request_id) def send_notification(self, method: str, params: Dict[str, object]): """