From 4aa4cc72d8cbdddd9923c4c7369bccb3cb8d7269 Mon Sep 17 00:00:00 2001 From: Didier Durand Date: Thu, 15 May 2025 05:52:31 +0200 Subject: [PATCH 1/2] adding 24 tests for client/errors.py --- tests/client/test_errors.py | 193 ++++++++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 tests/client/test_errors.py diff --git a/tests/client/test_errors.py b/tests/client/test_errors.py new file mode 100644 index 00000000..4887b122 --- /dev/null +++ b/tests/client/test_errors.py @@ -0,0 +1,193 @@ +import pytest + +from a2a.client import A2AClientHTTPError, A2AClientError, A2AClientJSONError + +class TestA2AClientError: + """Test cases for the base A2AClientError class.""" + + def test_instantiation(self): + """Test that A2AClientError can be instantiated.""" + error = A2AClientError("Test error message") + assert isinstance(error, Exception) + assert str(error) == "Test error message" + + def test_inheritance(self): + """Test that A2AClientError inherits from Exception.""" + error = A2AClientError() + assert isinstance(error, Exception) + + +class TestA2AClientHTTPError: + """Test cases for A2AClientHTTPError class.""" + + def test_instantiation(self): + """Test that A2AClientHTTPError can be instantiated with status_code and message.""" + error = A2AClientHTTPError(404, "Not Found") + assert isinstance(error, A2AClientError) + assert error.status_code == 404 + assert error.message == "Not Found" + + def test_message_formatting(self): + """Test that the error message is formatted correctly.""" + error = A2AClientHTTPError(500, "Internal Server Error") + assert str(error) == "HTTP Error 500: Internal Server Error" + + def test_inheritance(self): + """Test that A2AClientHTTPError inherits from A2AClientError.""" + error = A2AClientHTTPError(400, "Bad Request") + assert isinstance(error, A2AClientError) + + def test_with_empty_message(self): + """Test behavior with an empty message.""" + error = A2AClientHTTPError(403, "") + assert error.status_code == 403 + assert error.message == "" + assert str(error) == "HTTP Error 403: " + + def test_with_various_status_codes(self): + """Test with different HTTP status codes.""" + test_cases = [ + (200, "OK"), + (201, "Created"), + (400, "Bad Request"), + (401, "Unauthorized"), + (403, "Forbidden"), + (404, "Not Found"), + (500, "Internal Server Error"), + (503, "Service Unavailable") + ] + + for status_code, message in test_cases: + error = A2AClientHTTPError(status_code, message) + assert error.status_code == status_code + assert error.message == message + assert str(error) == f"HTTP Error {status_code}: {message}" + + +class TestA2AClientJSONError: + """Test cases for A2AClientJSONError class.""" + + def test_instantiation(self): + """Test that A2AClientJSONError can be instantiated with a message.""" + error = A2AClientJSONError("Invalid JSON format") + assert isinstance(error, A2AClientError) + assert error.message == "Invalid JSON format" + + def test_message_formatting(self): + """Test that the error message is formatted correctly.""" + error = A2AClientJSONError("Missing required field") + assert str(error) == "JSON Error: Missing required field" + + def test_inheritance(self): + """Test that A2AClientJSONError inherits from A2AClientError.""" + error = A2AClientJSONError("Parsing error") + assert isinstance(error, A2AClientError) + + def test_with_empty_message(self): + """Test behavior with an empty message.""" + error = A2AClientJSONError("") + assert error.message == "" + assert str(error) == "JSON Error: " + + def test_with_various_messages(self): + """Test with different error messages.""" + test_messages = [ + "Malformed JSON", + "Missing required fields", + "Invalid data type", + "Unexpected JSON structure", + "Empty JSON object" + ] + + for message in test_messages: + error = A2AClientJSONError(message) + assert error.message == message + assert str(error) == f"JSON Error: {message}" + + +class TestExceptionHierarchy: + """Test the exception hierarchy and relationships.""" + + def test_exception_hierarchy(self): + """Test that the exception hierarchy is correct.""" + assert issubclass(A2AClientError, Exception) + assert issubclass(A2AClientHTTPError, A2AClientError) + assert issubclass(A2AClientJSONError, A2AClientError) + + def test_catch_specific_exception(self): + """Test that specific exceptions can be caught.""" + try: + raise A2AClientHTTPError(404, "Not Found") + except A2AClientHTTPError as e: + assert e.status_code == 404 + assert e.message == "Not Found" + + def test_catch_base_exception(self): + """Test that derived exceptions can be caught as base exception.""" + exceptions = [ + A2AClientHTTPError(404, "Not Found"), + A2AClientJSONError("Invalid JSON") + ] + + for raised_error in exceptions: + try: + raise raised_error + except A2AClientError as e: + assert isinstance(e, A2AClientError) + + +class TestExceptionRaising: + """Test cases for raising and handling the exceptions.""" + + def test_raising_http_error(self): + """Test raising an HTTP error and checking its properties.""" + with pytest.raises(A2AClientHTTPError) as excinfo: + raise A2AClientHTTPError(429, "Too Many Requests") + + error = excinfo.value + assert error.status_code == 429 + assert error.message == "Too Many Requests" + assert str(error) == "HTTP Error 429: Too Many Requests" + + def test_raising_json_error(self): + """Test raising a JSON error and checking its properties.""" + with pytest.raises(A2AClientJSONError) as excinfo: + raise A2AClientJSONError("Invalid format") + + error = excinfo.value + assert error.message == "Invalid format" + assert str(error) == "JSON Error: Invalid format" + + def test_raising_base_error(self): + """Test raising the base error.""" + with pytest.raises(A2AClientError) as excinfo: + raise A2AClientError("Generic client error") + + assert str(excinfo.value) == "Generic client error" + + +# Additional parametrized tests for more comprehensive coverage + +@pytest.mark.parametrize("status_code,message,expected", [ + (400, "Bad Request", "HTTP Error 400: Bad Request"), + (404, "Not Found", "HTTP Error 404: Not Found"), + (500, "Server Error", "HTTP Error 500: Server Error"), +]) +def test_http_error_parametrized(status_code, message, expected): + """Parametrized test for HTTP errors with different status codes.""" + error = A2AClientHTTPError(status_code, message) + assert error.status_code == status_code + assert error.message == message + assert str(error) == expected + + +@pytest.mark.parametrize("message,expected", [ + ("Missing field", "JSON Error: Missing field"), + ("Invalid type", "JSON Error: Invalid type"), + ("Parsing failed", "JSON Error: Parsing failed"), +]) +def test_json_error_parametrized(message, expected): + """Parametrized test for JSON errors with different messages.""" + error = A2AClientJSONError(message) + assert error.message == message + assert str(error) == expected From 28a395035d9b380e55e8ff7d276b8d84a02e9935 Mon Sep 17 00:00:00 2001 From: Holt Skinner Date: Mon, 19 May 2025 16:33:29 -0700 Subject: [PATCH 2/2] Formatting --- tests/client/test_errors.py | 120 +++++++++++++++++++----------------- 1 file changed, 64 insertions(+), 56 deletions(-) diff --git a/tests/client/test_errors.py b/tests/client/test_errors.py index 4887b122..30c4468d 100644 --- a/tests/client/test_errors.py +++ b/tests/client/test_errors.py @@ -1,15 +1,16 @@ import pytest -from a2a.client import A2AClientHTTPError, A2AClientError, A2AClientJSONError +from a2a.client import A2AClientError, A2AClientHTTPError, A2AClientJSONError + class TestA2AClientError: """Test cases for the base A2AClientError class.""" def test_instantiation(self): """Test that A2AClientError can be instantiated.""" - error = A2AClientError("Test error message") + error = A2AClientError('Test error message') assert isinstance(error, Exception) - assert str(error) == "Test error message" + assert str(error) == 'Test error message' def test_inheritance(self): """Test that A2AClientError inherits from Exception.""" @@ -22,46 +23,46 @@ class TestA2AClientHTTPError: def test_instantiation(self): """Test that A2AClientHTTPError can be instantiated with status_code and message.""" - error = A2AClientHTTPError(404, "Not Found") + error = A2AClientHTTPError(404, 'Not Found') assert isinstance(error, A2AClientError) assert error.status_code == 404 - assert error.message == "Not Found" + assert error.message == 'Not Found' def test_message_formatting(self): """Test that the error message is formatted correctly.""" - error = A2AClientHTTPError(500, "Internal Server Error") - assert str(error) == "HTTP Error 500: Internal Server Error" + error = A2AClientHTTPError(500, 'Internal Server Error') + assert str(error) == 'HTTP Error 500: Internal Server Error' def test_inheritance(self): """Test that A2AClientHTTPError inherits from A2AClientError.""" - error = A2AClientHTTPError(400, "Bad Request") + error = A2AClientHTTPError(400, 'Bad Request') assert isinstance(error, A2AClientError) def test_with_empty_message(self): """Test behavior with an empty message.""" - error = A2AClientHTTPError(403, "") + error = A2AClientHTTPError(403, '') assert error.status_code == 403 - assert error.message == "" - assert str(error) == "HTTP Error 403: " + assert error.message == '' + assert str(error) == 'HTTP Error 403: ' def test_with_various_status_codes(self): """Test with different HTTP status codes.""" test_cases = [ - (200, "OK"), - (201, "Created"), - (400, "Bad Request"), - (401, "Unauthorized"), - (403, "Forbidden"), - (404, "Not Found"), - (500, "Internal Server Error"), - (503, "Service Unavailable") + (200, 'OK'), + (201, 'Created'), + (400, 'Bad Request'), + (401, 'Unauthorized'), + (403, 'Forbidden'), + (404, 'Not Found'), + (500, 'Internal Server Error'), + (503, 'Service Unavailable'), ] for status_code, message in test_cases: error = A2AClientHTTPError(status_code, message) assert error.status_code == status_code assert error.message == message - assert str(error) == f"HTTP Error {status_code}: {message}" + assert str(error) == f'HTTP Error {status_code}: {message}' class TestA2AClientJSONError: @@ -69,40 +70,40 @@ class TestA2AClientJSONError: def test_instantiation(self): """Test that A2AClientJSONError can be instantiated with a message.""" - error = A2AClientJSONError("Invalid JSON format") + error = A2AClientJSONError('Invalid JSON format') assert isinstance(error, A2AClientError) - assert error.message == "Invalid JSON format" + assert error.message == 'Invalid JSON format' def test_message_formatting(self): """Test that the error message is formatted correctly.""" - error = A2AClientJSONError("Missing required field") - assert str(error) == "JSON Error: Missing required field" + error = A2AClientJSONError('Missing required field') + assert str(error) == 'JSON Error: Missing required field' def test_inheritance(self): """Test that A2AClientJSONError inherits from A2AClientError.""" - error = A2AClientJSONError("Parsing error") + error = A2AClientJSONError('Parsing error') assert isinstance(error, A2AClientError) def test_with_empty_message(self): """Test behavior with an empty message.""" - error = A2AClientJSONError("") - assert error.message == "" - assert str(error) == "JSON Error: " + error = A2AClientJSONError('') + assert error.message == '' + assert str(error) == 'JSON Error: ' def test_with_various_messages(self): """Test with different error messages.""" test_messages = [ - "Malformed JSON", - "Missing required fields", - "Invalid data type", - "Unexpected JSON structure", - "Empty JSON object" + 'Malformed JSON', + 'Missing required fields', + 'Invalid data type', + 'Unexpected JSON structure', + 'Empty JSON object', ] for message in test_messages: error = A2AClientJSONError(message) assert error.message == message - assert str(error) == f"JSON Error: {message}" + assert str(error) == f'JSON Error: {message}' class TestExceptionHierarchy: @@ -117,16 +118,16 @@ def test_exception_hierarchy(self): def test_catch_specific_exception(self): """Test that specific exceptions can be caught.""" try: - raise A2AClientHTTPError(404, "Not Found") + raise A2AClientHTTPError(404, 'Not Found') except A2AClientHTTPError as e: assert e.status_code == 404 - assert e.message == "Not Found" + assert e.message == 'Not Found' def test_catch_base_exception(self): """Test that derived exceptions can be caught as base exception.""" exceptions = [ - A2AClientHTTPError(404, "Not Found"), - A2AClientJSONError("Invalid JSON") + A2AClientHTTPError(404, 'Not Found'), + A2AClientJSONError('Invalid JSON'), ] for raised_error in exceptions: @@ -142,37 +143,41 @@ class TestExceptionRaising: def test_raising_http_error(self): """Test raising an HTTP error and checking its properties.""" with pytest.raises(A2AClientHTTPError) as excinfo: - raise A2AClientHTTPError(429, "Too Many Requests") + raise A2AClientHTTPError(429, 'Too Many Requests') error = excinfo.value assert error.status_code == 429 - assert error.message == "Too Many Requests" - assert str(error) == "HTTP Error 429: Too Many Requests" + assert error.message == 'Too Many Requests' + assert str(error) == 'HTTP Error 429: Too Many Requests' def test_raising_json_error(self): """Test raising a JSON error and checking its properties.""" with pytest.raises(A2AClientJSONError) as excinfo: - raise A2AClientJSONError("Invalid format") + raise A2AClientJSONError('Invalid format') error = excinfo.value - assert error.message == "Invalid format" - assert str(error) == "JSON Error: Invalid format" + assert error.message == 'Invalid format' + assert str(error) == 'JSON Error: Invalid format' def test_raising_base_error(self): """Test raising the base error.""" with pytest.raises(A2AClientError) as excinfo: - raise A2AClientError("Generic client error") + raise A2AClientError('Generic client error') - assert str(excinfo.value) == "Generic client error" + assert str(excinfo.value) == 'Generic client error' # Additional parametrized tests for more comprehensive coverage -@pytest.mark.parametrize("status_code,message,expected", [ - (400, "Bad Request", "HTTP Error 400: Bad Request"), - (404, "Not Found", "HTTP Error 404: Not Found"), - (500, "Server Error", "HTTP Error 500: Server Error"), -]) + +@pytest.mark.parametrize( + 'status_code,message,expected', + [ + (400, 'Bad Request', 'HTTP Error 400: Bad Request'), + (404, 'Not Found', 'HTTP Error 404: Not Found'), + (500, 'Server Error', 'HTTP Error 500: Server Error'), + ], +) def test_http_error_parametrized(status_code, message, expected): """Parametrized test for HTTP errors with different status codes.""" error = A2AClientHTTPError(status_code, message) @@ -181,11 +186,14 @@ def test_http_error_parametrized(status_code, message, expected): assert str(error) == expected -@pytest.mark.parametrize("message,expected", [ - ("Missing field", "JSON Error: Missing field"), - ("Invalid type", "JSON Error: Invalid type"), - ("Parsing failed", "JSON Error: Parsing failed"), -]) +@pytest.mark.parametrize( + 'message,expected', + [ + ('Missing field', 'JSON Error: Missing field'), + ('Invalid type', 'JSON Error: Invalid type'), + ('Parsing failed', 'JSON Error: Parsing failed'), + ], +) def test_json_error_parametrized(message, expected): """Parametrized test for JSON errors with different messages.""" error = A2AClientJSONError(message)