Skip to content

Commit

Permalink
moved tests
Browse files Browse the repository at this point in the history
  • Loading branch information
sanderegg committed Oct 25, 2024
1 parent 2f21f97 commit d626e40
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 69 deletions.
97 changes: 97 additions & 0 deletions packages/common-library/tests/test_json_serialization.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# pylint: disable=redefined-outer-name
# pylint: disable=unused-argument
# pylint: disable=unused-variable

import json
from copy import deepcopy
from typing import Annotated, Any, TypeAlias
from uuid import uuid4

import pytest
from common_library.json_serialization import (
JsonNamespace,
SeparatorTuple,
json_dumps,
json_loads,
)
from faker import Faker
from pydantic import Field, TypeAdapter
from pydantic.json import pydantic_encoder


@pytest.fixture
def fake_data_dict(faker: Faker) -> dict[str, Any]:
data = {
"uuid_as_UUID": faker.uuid4(cast_to=None),
"uuid_as_str": faker.uuid4(),
"int": faker.pyint(),
"float": faker.pyfloat(),
"str": faker.pystr(),
"dict": faker.pydict(),
"list": faker.pylist(),
}
data["object"] = deepcopy(data)
return data


def test_json_dump_variants():

uuid_obj = uuid4()

with pytest.raises(TypeError) as exc_info:
json.dumps(uuid_obj)

assert str(exc_info.value) == "Object of type UUID is not JSON serializable"

assert json_dumps(uuid_obj) == json.dumps(str(uuid_obj))


def test_serialized_non_str_dict_keys():
# tests orjson.OPT_NON_STR_KEYS option

# if a dict has a key of a type other than str it will NOT raise
json_dumps({1: "foo"})


ConstrainedFloat: TypeAlias = Annotated[float, Field(ge=0.0, le=1.0)]


def test_serialized_constraint_floats():
# test extension of ENCODERS_BY_TYPE used in pydantic_encoder

json_dumps({"value": 1.0})

# TypeError: Type is not JSON serializable: ProgressPercent
json_dumps({"value": TypeAdapter(ConstrainedFloat).validate_python(1.0)})


def _expected_json_dumps(obj: Any, default=pydantic_encoder, **json_dumps_kwargs):
if "indent" not in json_dumps_kwargs:
json_dumps_kwargs.setdefault(
"separators",
SeparatorTuple(item_separator=",", key_separator=":"), # compact separators
)
return json.dumps(obj, default=default, **json_dumps_kwargs)


@pytest.mark.parametrize(
"kwargs",
[
pytest.param({}, id="no-kw"),
pytest.param({"sort_keys": True}, id="sort_keys-kw"),
pytest.param(
{"separators": (",", ":")}, id="default_separators-kw"
), # NOTE: e.g. engineio.packet has `self.json.dumps(self.data, separators=(',', ':'))`
pytest.param(
{"indent": 2}, id="indent-kw"
), # NOTE: only one-to-one with indent=2
],
)
def test_compatiblity_with_json_interface(
fake_data_dict: dict[str, Any], kwargs: dict[str, Any]
):
orjson_dump = JsonNamespace.dumps(fake_data_dict, **kwargs)
json_dump = _expected_json_dumps(fake_data_dict, **kwargs)

# NOTE: cannot compare dumps directly because orjson compacts it more
assert json_loads(orjson_dump) == json_loads(json_dump)
70 changes: 1 addition & 69 deletions packages/models-library/tests/test_utils_json_serialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,14 @@
# pylint: disable=unused-variable


import json
from copy import deepcopy
from typing import Any
from uuid import uuid4

import pytest
from common_library.json_serialization import (
JsonNamespace,
SeparatorTuple,
json_dumps,
json_loads,
)
from common_library.json_serialization import json_dumps, json_loads
from faker import Faker
from models_library.api_schemas_long_running_tasks.base import ProgressPercent
from models_library.utils.fastapi_encoders import jsonable_encoder
from pydantic.json import pydantic_encoder


def _expected_json_dumps(obj: Any, default=pydantic_encoder, **json_dumps_kwargs):
if "indent" not in json_dumps_kwargs:
json_dumps_kwargs.setdefault(
"separators",
SeparatorTuple(item_separator=",", key_separator=":"), # compact separators
)
return json.dumps(obj, default=default, **json_dumps_kwargs)


def test_json_dump_variants():

uuid_obj = uuid4()

with pytest.raises(TypeError) as exc_info:
json.dumps(uuid_obj)

assert str(exc_info.value) == "Object of type UUID is not JSON serializable"

assert json_dumps(uuid_obj) == json.dumps(str(uuid_obj))


@pytest.fixture
Expand Down Expand Up @@ -75,42 +46,3 @@ def test_serialization_of_nested_dicts(fake_data_dict: dict[str, Any]):

dump = json_dumps(obj)
assert json_loads(dump) == jsonable_encoder(obj)


@pytest.mark.parametrize(
"kwargs",
[
pytest.param({}, id="no-kw"),
pytest.param({"sort_keys": True}, id="sort_keys-kw"),
pytest.param(
{"separators": (",", ":")}, id="default_separators-kw"
), # NOTE: e.g. engineio.packet has `self.json.dumps(self.data, separators=(',', ':'))`
pytest.param(
{"indent": 2}, id="indent-kw"
), # NOTE: only one-to-one with indent=2
],
)
def test_compatiblity_with_json_interface(
fake_data_dict: dict[str, Any], kwargs: dict[str, Any]
):
orjson_dump = JsonNamespace.dumps(fake_data_dict, **kwargs)
json_dump = _expected_json_dumps(fake_data_dict, **kwargs)

# NOTE: cannot compare dumps directly because orjson compacts it more
assert json_loads(orjson_dump) == json_loads(json_dump)


def test_serialized_non_str_dict_keys():
# tests orjson.OPT_NON_STR_KEYS option

# if a dict has a key of a type other than str it will NOT raise
json_dumps({1: "foo"})


def test_serialized_constraint_floats():
# test extension of ENCODERS_BY_TYPE used in pydantic_encoder

json_dumps({"value": 1.0})

# TypeError: Type is not JSON serializable: ProgressPercent
json_dumps({"value": ProgressPercent(1.0)})

0 comments on commit d626e40

Please sign in to comment.