Skip to content

Commit

Permalink
increase coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
acidjunk committed Oct 18, 2024
1 parent 9cd26ba commit a4d31d2
Show file tree
Hide file tree
Showing 3 changed files with 207 additions and 2 deletions.
4 changes: 2 additions & 2 deletions pydantic_forms/utils/json.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def from_serializable(dct: dict[str, Any]) -> dict[str, Any]:


if IS_ORJSON:
print("Using orjson") # noqa
logger.debug("Using orjson")

def json_loads(s: Union[str, bytes, bytearray]) -> PY_JSON_TYPES:
o = orjson.loads(s)
Expand All @@ -192,7 +192,7 @@ def json_dumps(obj: PY_JSON_TYPES, default: Callable = to_serializable) -> str:
raise e

else:
print("Using stdlib json") # noqa
logger.debug("Using stdlib json")
json_loads = json.loads
json_dumps = partial(json.dumps, default=to_serializable)

Expand Down
100 changes: 100 additions & 0 deletions tests/unit_tests/test_utils_from_serializable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import pytest
from datetime import datetime

from pydantic_forms.utils.json import from_serializable


# Helper function for testing ISO formatted datetime
def test_from_serializable_datetime():
iso_datetime = "2024-01-01T12:00:00+00:00"
input_dict = {"timestamp": iso_datetime}
expected_datetime = datetime.fromisoformat(iso_datetime)

result = from_serializable(input_dict)

assert isinstance(result["timestamp"], datetime)
assert result["timestamp"] == expected_datetime


# Test that the function does not convert non-ISO format strings
def test_from_serializable_non_iso_string():
input_dict = {"non_iso": "some random string"}

result = from_serializable(input_dict)

assert result["non_iso"] == "some random string" # No conversion


# Test that no conversion happens if string is not in ISO format but looks similar
def test_from_serializable_non_iso_similar_string():
similar_string = "2024-01-01 12:00:00"
input_dict = {"similar_string": similar_string}

result = from_serializable(input_dict)

assert result["similar_string"] == similar_string # No conversion


# Test handling of invalid ISO string that should not raise an error
def test_from_serializable_invalid_iso_string():
invalid_iso = "2024-01-01T12:00:00" # Missing timezone information
input_dict = {"timestamp": invalid_iso}

result = from_serializable(input_dict)

assert result["timestamp"] == invalid_iso # No conversion should happen


# Test multiple fields in dictionary, only ISO string should be converted
def test_from_serializable_mixed_dict():
iso_datetime = "2024-01-01T12:00:00+00:00"
input_dict = {
"timestamp": iso_datetime,
"non_iso": "hello",
"integer": 42,
}

result = from_serializable(input_dict)

# Check only the datetime field is converted
assert isinstance(result["timestamp"], datetime)
assert result["timestamp"] == datetime.fromisoformat(iso_datetime)
assert result["non_iso"] == "hello"
assert result["integer"] == 42


# Test that function handles empty dict correctly
def test_from_serializable_empty_dict():
input_dict = {}

result = from_serializable(input_dict)

assert result == {} # Should return an empty dict


# Test for non-string types
def test_from_serializable_non_string_values():
input_dict = {
"timestamp": "2024-01-01T12:00:00+00:00",
"number": 123,
"list": [1, 2, 3],
"none_value": None,
}

result = from_serializable(input_dict)

assert isinstance(result["timestamp"], datetime)
assert result["number"] == 123
assert result["list"] == [1, 2, 3]
assert result["none_value"] is None


# Test when the timestamp is in a nested dictionary
def test_from_serializable_nested_dict():
iso_datetime = "2024-01-01T12:00:00+00:00"
input_dict = {"level1": {"timestamp": iso_datetime}}

result = from_serializable(input_dict)

# Since this function works on top-level only, the nested timestamp should not be converted
assert result["level1"]["timestamp"] == iso_datetime # No conversion
105 changes: 105 additions & 0 deletions tests/unit_tests/test_utils_to_serializable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
# Test UUID serialization
from dataclasses import dataclass, asdict
from datetime import datetime
from ipaddress import IPv4Network, IPv6Network, IPv4Address, IPv6Address
from uuid import UUID

from pydantic_forms.utils.json import to_serializable
import pytest


def test_to_serializable_uuid():
test_uuid = UUID("12345678123456781234567812345678")
assert to_serializable(test_uuid) == str(test_uuid)


# Test IPv4 and IPv6 Address serialization
@pytest.mark.parametrize(
"ip_address, expected",
[
(IPv4Address("192.168.1.1"), "192.168.1.1"),
(IPv6Address("2001:db8::8a2e:370:7334"), "2001:db8::8a2e:370:7334"),
],
)
def test_to_serializable_ip_address(ip_address, expected):
assert to_serializable(ip_address) == expected


# Test IPv4 and IPv6 Network serialization
@pytest.mark.parametrize(
"ip_network, expected",
[
(IPv4Network("192.168.1.0/24"), "192.168.1.0/24"),
(IPv6Network("2001:db8::/32"), "2001:db8::/32"),
],
)
def test_to_serializable_ip_network(ip_network, expected):
assert to_serializable(ip_network) == expected


# Test datetime serialization
def test_to_serializable_datetime():
test_datetime = datetime(2024, 1, 1)
assert to_serializable(test_datetime) == "2024-01-01T00:00:00"


# Test dataclass serialization
@dataclass
class TestDataClass:
id: int
name: str


def test_to_serializable_dataclass():
obj = TestDataClass(id=1, name="Test")
assert to_serializable(obj) == asdict(obj)


# Test custom JSON method
class CustomJsonObject:
def __json__(self):
return {"custom": "json"}


def test_to_serializable_custom_json():
obj = CustomJsonObject()
assert to_serializable(obj) == {"custom": "json"}


# Test custom to_dict method
class CustomDictObject:
def to_dict(self):
return {"custom": "dict"}


def test_to_serializable_custom_dict():
obj = CustomDictObject()
assert to_serializable(obj) == {"custom": "dict"}


# Test set serialization
def test_to_serializable_set():
test_set = {1, 2, 3}
assert to_serializable(test_set) == list(test_set)


# Test ValueError and AssertionError serialization
@pytest.mark.parametrize(
"exception, expected",
[
(ValueError("An error occurred"), "An error occurred"),
(AssertionError("Assertion failed"), "Assertion failed"),
],
)
def test_to_serializable_exceptions(exception, expected):
assert to_serializable(exception) == expected


# Test TypeError raised for unsupported types
def test_to_serializable_unsupported_type():
class UnsupportedClass:
pass

obj = UnsupportedClass()
with pytest.raises(TypeError, match="Could not serialize object of type UnsupportedClass to JSON"):
to_serializable(obj)

0 comments on commit a4d31d2

Please sign in to comment.