-
-
Notifications
You must be signed in to change notification settings - Fork 32
feat: add tests for utils as well #241
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,310 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Test module for json2xml.utils functionality.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import json | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import tempfile | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from typing import TYPE_CHECKING | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from unittest.mock import Mock, patch | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import pytest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from json2xml.utils import ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| InvalidDataError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| JSONReadError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| StringReadError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| URLReadError, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| readfromjson, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| readfromstring, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| readfromurl, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if TYPE_CHECKING: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from _pytest.capture import CaptureFixture | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from _pytest.fixtures import FixtureRequest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Check noticeCode scanning / CodeQL Unused import Note test
Import of 'FixtureRequest' is not used.
Copilot AutofixAI 7 months ago To fix the issue, the unused import of
Suggested changeset
1
tests/test_utils.py
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from _pytest.logging import LogCaptureFixture | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Check noticeCode scanning / CodeQL Unused import Note test
Import of 'LogCaptureFixture' is not used.
Copilot AutofixAI 7 months ago To fix the problem, the unused import statement for
Suggested changeset
1
tests/test_utils.py
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from _pytest.monkeypatch import MonkeyPatch | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Check noticeCode scanning / CodeQL Unused import Note test
Import of 'MonkeyPatch' is not used.
Copilot AutofixAI 7 months ago To fix the issue, the unused import statement for
Suggested changeset
1
tests/test_utils.py
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from pytest_mock.plugin import MockerFixture | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Check noticeCode scanning / CodeQL Unused import Note test
Import of 'MockerFixture' is not used.
Copilot AutofixAI 7 months ago To fix the problem, we should remove the unused import
Suggested changeset
1
tests/test_utils.py
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| class TestExceptions: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Test custom exception classes.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_json_read_error(self) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Test JSONReadError exception.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with pytest.raises(JSONReadError) as exc_info: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| raise JSONReadError("Test error message") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert str(exc_info.value) == "Test error message" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Check warningCode scanning / CodeQL Unreachable code Warning test
This statement is unreachable.
Copilot AutofixAI 7 months ago To fix the issue, the
Suggested changeset
1
tests/test_utils.py
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_invalid_data_error(self) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Test InvalidDataError exception.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with pytest.raises(InvalidDataError) as exc_info: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| raise InvalidDataError("Invalid data") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert str(exc_info.value) == "Invalid data" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Check warningCode scanning / CodeQL Unreachable code Warning test
This statement is unreachable.
Copilot AutofixAI 7 months ago To fix the issue, the unreachable
Suggested changeset
1
tests/test_utils.py
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_url_read_error(self) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Test URLReadError exception.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with pytest.raises(URLReadError) as exc_info: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| raise URLReadError("URL error") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert str(exc_info.value) == "URL error" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Check warningCode scanning / CodeQL Unreachable code Warning test
This statement is unreachable.
Copilot AutofixAI 7 months ago To fix the issue, the unreachable The fix involves:
Suggested changeset
1
tests/test_utils.py
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_string_read_error(self) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Test StringReadError exception.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with pytest.raises(StringReadError) as exc_info: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| raise StringReadError("String error") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert str(exc_info.value) == "String error" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Check warningCode scanning / CodeQL Unreachable code Warning test
This statement is unreachable.
Copilot AutofixAI 7 months ago To fix the issue, the unreachable assertion on line 52 should be moved inside the Steps:
Suggested changeset
1
tests/test_utils.py
Copilot is powered by AI and may make mistakes. Always verify output.
Refresh and try again.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| class TestReadFromJson: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Test readfromjson function.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+55
to
+56
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. suggestion (testing): Add tests for Add tests for empty files (should raise JSONReadError) and for files with valid non-object JSON (should raise an appropriate error, given the function's dict return type).
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_readfromjson_valid_file(self) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Test reading a valid JSON file.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| test_data = {"key": "value", "number": 42} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| json.dump(test_data, f) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| temp_filename = f.name | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| result = readfromjson(temp_filename) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| assert result == test_data | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| finally: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import os | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| os.unlink(temp_filename) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_readfromjson_invalid_json_content(self) -> None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| """Test reading a file with invalid JSON content.""" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| f.write('{"invalid": json content}') # Invalid JSON | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| temp_filename = f.name | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| try: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| with pytest.raises(JSONReadError, match="Invalid JSON File"): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| readfromjson(temp_filename) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| finally: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| import os | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| os.unlink(temp_filename) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+58
to
+84
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def test_readfromjson_valid_file(self) -> None: | |
| """Test reading a valid JSON file.""" | |
| test_data = {"key": "value", "number": 42} | |
| with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: | |
| json.dump(test_data, f) | |
| temp_filename = f.name | |
| try: | |
| result = readfromjson(temp_filename) | |
| assert result == test_data | |
| finally: | |
| import os | |
| os.unlink(temp_filename) | |
| def test_readfromjson_invalid_json_content(self) -> None: | |
| """Test reading a file with invalid JSON content.""" | |
| with tempfile.NamedTemporaryFile(mode='w', suffix='.json', delete=False) as f: | |
| f.write('{"invalid": json content}') # Invalid JSON | |
| temp_filename = f.name | |
| try: | |
| with pytest.raises(JSONReadError, match="Invalid JSON File"): | |
| readfromjson(temp_filename) | |
| finally: | |
| import os | |
| os.unlink(temp_filename) | |
| def test_readfromjson_valid_file(self, tmp_path) -> None: | |
| """Test reading a valid JSON file.""" | |
| test_data = {"key": "value", "number": 42} | |
| temp_file = tmp_path / "test.json" | |
| temp_file.write_text(json.dumps(test_data)) | |
| result = readfromjson(str(temp_file)) | |
| assert result == test_data | |
| def test_readfromjson_invalid_json_content(self, tmp_path) -> None: | |
| """Test reading a file with invalid JSON content.""" | |
| temp_file = tmp_path / "invalid.json" | |
| temp_file.write_text('{"invalid": json content}') # Invalid JSON | |
| with pytest.raises(JSONReadError, match="Invalid JSON File"): | |
| readfromjson(str(temp_file)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (testing): Enhance TestReadFromUrl with tests for network-level errors.
Add tests that mock mock_http.request to raise exceptions like TimeoutError and NewConnectionError, and verify that readfromurl responds appropriately, such as by raising URLReadError.
| class TestReadFromUrl: | |
| """Test readfromurl function.""" | |
| from requests.exceptions import Timeout, ConnectionError | |
| import urllib3 | |
| class TestReadFromUrl: | |
| """Test readfromurl function.""" | |
| @patch("json2xml.utils.http") | |
| def test_readfromurl_timeout_error(self, mock_http: Mock) -> None: | |
| """Test readfromurl raises URLReadError on TimeoutError.""" | |
| mock_http.request.side_effect = Timeout("Request timed out") | |
| with pytest.raises(URLReadError, match="URL Read Error"): | |
| readfromurl("http://example.com") | |
| @patch("json2xml.utils.http") | |
| def test_readfromurl_new_connection_error(self, mock_http: Mock) -> None: | |
| """Test readfromurl raises URLReadError on NewConnectionError.""" | |
| mock_http.request.side_effect = urllib3.exceptions.NewConnectionError( | |
| None, "Failed to establish a new connection" | |
| ) | |
| with pytest.raises(URLReadError, match="URL Read Error"): | |
| readfromurl("http://example.com") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion: Consider consistent error wrapping for JSONDecodeError in readfromurl.
Decide if readfromurl should wrap json.JSONDecodeError in a custom error for consistency with TestReadFromJson. If so, update this test to expect the custom error instead of the raw exception.
Suggested implementation:
with pytest.raises(JSONReadError):
readfromurl("http://example.com/invalid.json")You must also update the implementation of readfromurl (likely in json2xml/utils.py) to catch json.JSONDecodeError and raise JSONReadError instead. For example:
import json
def readfromurl(url):
...
try:
data = json.loads(response.data.decode("utf-8"))
except json.JSONDecodeError as e:
raise JSONReadError("Invalid JSON data") from e
...There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (testing): Test readfromstring with valid JSON strings that are not dictionary objects.
Add tests for valid JSON inputs that are not dictionaries (e.g., arrays, null, booleans, numbers, strings) to ensure readfromstring raises an appropriate error for type mismatches.
| class TestReadFromString: | |
| """Test readfromstring function.""" | |
| class TestReadFromString: | |
| """Test readfromstring function.""" | |
| @pytest.mark.parametrize( | |
| "json_input", | |
| [ | |
| '["array", "of", "values"]', | |
| 'null', | |
| 'true', | |
| 'false', | |
| '123', | |
| '"just a string"', | |
| '3.14' | |
| ] | |
| ) | |
| def test_readfromstring_non_dict_types(self, json_input): | |
| """readfromstring should raise InvalidDataError for non-dict JSON inputs.""" | |
| with pytest.raises(InvalidDataError): | |
| readfromstring(json_input) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
suggestion (testing): Add an integration test for readfromjson chained with dicttoxml.
An integration test for readfromjson with dicttoxml should be added to match the coverage described in the PR.
| readfromstring("this is just plain text") | |
| class TestIntegration: | |
| """Integration tests combining multiple utilities.""" | |
| readfromstring("this is just plain text") | |
| class TestIntegration: | |
| """Integration tests combining multiple utilities.""" | |
| def test_readfromjson_chained_with_dicttoxml(self): | |
| """Test chaining readfromjson with dicttoxml.""" | |
| from json2xml.utils import readfromjson | |
| from json2xml import dicttoxml | |
| json_input = '{"foo": "bar", "baz": 123}' | |
| data = readfromjson(json_input) | |
| xml_output = dicttoxml(data) | |
| assert "<foo>bar</foo>" in xml_output | |
| assert "<baz>123</baz>" in xml_output | |
Check notice
Code scanning / CodeQL
Unused import Note test
Copilot Autofix
AI 7 months ago
To fix the issue, we will remove the unused import of
CaptureFixturefrom theTYPE_CHECKINGblock. This will clean up the code and eliminate the unnecessary dependency. No other changes are required, as this does not affect the functionality of the code.