diff options
Diffstat (limited to 'tests/test_client.py')
-rw-r--r-- | tests/test_client.py | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/tests/test_client.py b/tests/test_client.py new file mode 100644 index 0000000..cacd3e0 --- /dev/null +++ b/tests/test_client.py @@ -0,0 +1,102 @@ +############################################################################ +# Copyright(c) Open Law Library. All rights reserved. # +# See ThirdPartyNotices.txt in the project root for additional notices. # +# # +# Licensed under the Apache License, Version 2.0 (the "License") # +# you may not use this file except in compliance with the License. # +# You may obtain a copy of the License at # +# # +# http: // www.apache.org/licenses/LICENSE-2.0 # +# # +# Unless required by applicable law or agreed to in writing, software # +# 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. # +############################################################################ +import asyncio +import pathlib +import sys +from typing import Union + +import pytest +from pygls import IS_PYODIDE + +from pygls.client import JsonRPCClient +from pygls.exceptions import JsonRpcException, PyglsError + + +SERVERS = pathlib.Path(__file__).parent / "servers" + + +@pytest.mark.asyncio +@pytest.mark.skipif(IS_PYODIDE, reason="Subprocesses are not available on pyodide.") +async def test_client_detect_server_exit(): + """Ensure that the client detects when the server process exits.""" + + class TestClient(JsonRPCClient): + server_exit_called = False + + async def server_exit(self, server: asyncio.subprocess.Process): + self.server_exit_called = True + assert server.returncode == 0 + + client = TestClient() + await client.start_io(sys.executable, "-c", "print('Hello, World!')") + await asyncio.sleep(1) + await client.stop() + + message = "Expected the `server_exit` method to have been called." + assert client.server_exit_called, message + + +@pytest.mark.asyncio +@pytest.mark.skipif(IS_PYODIDE, reason="Subprocesses are not available on pyodide.") +async def test_client_detect_invalid_json(): + """Ensure that the client can detect the case where the server returns invalid + json.""" + + class TestClient(JsonRPCClient): + report_error_called = False + future = None + + def report_server_error( + self, error: Exception, source: Union[PyglsError, JsonRpcException] + ): + self.report_error_called = True + self.future.cancel() + + self._server.kill() + self._stop_event.set() + + assert "Unterminated string" in str(error) + + client = TestClient() + await client.start_io(sys.executable, str(SERVERS / "invalid_json.py")) + + future = client.protocol.send_request_async("method/name", {}) + client.future = future + + try: + await future + except asyncio.CancelledError: + pass # Ignore the exception generated by cancelling the future + finally: + await client.stop() + + assert_message = "Expected `report_server_error` to have been called" + assert client.report_error_called, assert_message + + +@pytest.mark.asyncio +@pytest.mark.skipif(IS_PYODIDE, reason="Subprocesses are not available on pyodide.") +async def test_client_large_responses(): + """Ensure that the client can correctly handle large responses from a server.""" + + client = JsonRPCClient() + await client.start_io(sys.executable, str(SERVERS / "large_response.py")) + + result = await client.protocol.send_request_async("get/numbers", {}, msg_id=1) + assert len(result.numbers) == 100_000 + + await client.stop() |