# Path: tests/entities.py
# class DataClassIntImmutableDefault(DataClassJsonMixin):
#     x: int = 0
# 
# class DataClassMutableDefaultDict(DataClassJsonMixin):
#     xs: Dict[str, int] = field(default_factory=dict)
# 
# class DataClassMutableDefaultList(DataClassJsonMixin):
#     xs: List[int] = field(default_factory=list)
# 
# class DataClassWithDeque(DataClassJsonMixin):
#     xs: Deque[int]
# 
# class DataClassWithDict(DataClassJsonMixin):
#     kvs: Dict[str, str]
# 
# class DataClassWithDictInt(DataClassJsonMixin):
#     kvs: Dict[int, str]
# 
# class DataClassWithFrozenSet(DataClassJsonMixin):
#     xs: FrozenSet[int]
# 
# class DataClassWithList(DataClassJsonMixin):
#     xs: List[int]
# 
# class DataClassWithListStr(DataClassJsonMixin):
#     xs: List[str]
# 
# class DataClassWithMyCollection(DataClassJsonMixin):
#     xs: MyCollection[int]
# 
# class DataClassWithOptional(DataClassJsonMixin):
#     x: Optional[int]
# 
# class DataClassWithOptionalStr(DataClassJsonMixin):
#     x: Optional[str] = None
# 
# class DataClassWithSet(DataClassJsonMixin):
#     xs: Set[int]
# 
# class DataClassWithTuple(DataClassJsonMixin):
#     xs: Tuple[int]
# 
# class DataClassWithUnionIntNone(DataClassJsonMixin):
#     x: Union[int, None]
# 
# class MyCollection(Collection[A]):
#     def __init__(self, xs: Collection[A]) -> None:
#         self.xs = xs
# 
#     def __contains__(self, item):
#         return False
# 
#     def __iter__(self):
#         return iter(self.xs)
# 
#     def __len__(self):
#         return len(self.xs)
# 
#     def __eq__(self, other):
#         return type(self) == type(other) and self.xs == other.xs


from collections import deque
from tests.entities import (DataClassIntImmutableDefault,
                            DataClassMutableDefaultDict,
                            DataClassMutableDefaultList, DataClassWithDeque,
                            DataClassWithDict, DataClassWithDictInt,
                            DataClassWithFrozenSet, DataClassWithList,
                            DataClassWithListStr, DataClassWithMyCollection,
                            DataClassWithOptional, DataClassWithOptionalStr,
                            DataClassWithSet, DataClassWithTuple,
                            DataClassWithUnionIntNone, MyCollection)

    def test_my_collection(self):
        assert DataClassWithMyCollection(
            MyCollection([1])).to_json() == '{"xs": [1]}'

    def test_immutable_default(self):
        assert DataClassIntImmutableDefault().to_json() == '{"x": 0}'

    def test_mutable_default_list(self):
        assert DataClassMutableDefaultList().to_json() == '{"xs": []}'

    def test_mutable_default_dict(self):
        assert DataClassMutableDefaultDict().to_json() == '{"xs": {}}'


class TestDecoder:
    def test_list(self):
        assert (DataClassWithList.from_json('{"xs": [1]}') ==
                DataClassWithList([1]))

    def test_list_str(self):
        assert (DataClassWithListStr.from_json('{"xs": ["1"]}') ==
                DataClassWithListStr(["1"]))

    def test_dict(self):
        assert (DataClassWithDict.from_json('{"kvs": {"1": "a"}}') ==
                DataClassWithDict({'1': 'a'}))

    def test_dict_int(self):
        assert (DataClassWithDictInt.from_json('{"kvs": {"1": "a"}}') ==

# Path: tests/entities.py
# class DataClassIntImmutableDefault(DataClassJsonMixin):
#     x: int = 0
# 
# class DataClassMutableDefaultDict(DataClassJsonMixin):
#     xs: Dict[str, int] = field(default_factory=dict)
# 
# class DataClassMutableDefaultList(DataClassJsonMixin):
#     xs: List[int] = field(default_factory=list)
# 
# class DataClassWithDeque(DataClassJsonMixin):
#     xs: Deque[int]
# 
# class DataClassWithDict(DataClassJsonMixin):
#     kvs: Dict[str, str]
# 
# class DataClassWithDictInt(DataClassJsonMixin):
#     kvs: Dict[int, str]
# 
# class DataClassWithFrozenSet(DataClassJsonMixin):
#     xs: FrozenSet[int]
# 
# class DataClassWithList(DataClassJsonMixin):
#     xs: List[int]
# 
# class DataClassWithListStr(DataClassJsonMixin):
#     xs: List[str]
# 
# class DataClassWithMyCollection(DataClassJsonMixin):
#     xs: MyCollection[int]
# 
# class DataClassWithOptional(DataClassJsonMixin):
#     x: Optional[int]
# 
# class DataClassWithOptionalStr(DataClassJsonMixin):
#     x: Optional[str] = None
# 
# class DataClassWithSet(DataClassJsonMixin):
#     xs: Set[int]
# 
# class DataClassWithTuple(DataClassJsonMixin):
#     xs: Tuple[int]
# 
# class DataClassWithUnionIntNone(DataClassJsonMixin):
#     x: Union[int, None]
# 
# class MyCollection(Collection[A]):
#     def __init__(self, xs: Collection[A]) -> None:
#         self.xs = xs
# 
#     def __contains__(self, item):
#         return False
# 
#     def __iter__(self):
#         return iter(self.xs)
# 
#     def __len__(self):
#         return len(self.xs)
# 
#     def __eq__(self, other):
#         return type(self) == type(other) and self.xs == other.xs


# Path: tests/test_collections.py
from collections import deque
from tests.entities import (DataClassIntImmutableDefault,
                            DataClassMutableDefaultDict,
                            DataClassMutableDefaultList, DataClassWithDeque,
                            DataClassWithDict, DataClassWithDictInt,
                            DataClassWithFrozenSet, DataClassWithList,
                            DataClassWithListStr, DataClassWithMyCollection,
                            DataClassWithOptional, DataClassWithOptionalStr,
                            DataClassWithSet, DataClassWithTuple,
                            DataClassWithUnionIntNone, MyCollection)


    def test_my_collection(self):
        assert DataClassWithMyCollection(
            MyCollection([1])).to_json() == '{"xs": [1]}'

    def test_immutable_default(self):
        assert DataClassIntImmutableDefault().to_json() == '{"x": 0}'

    def test_mutable_default_list(self):
        assert DataClassMutableDefaultList().to_json() == '{"xs": []}'

    def test_mutable_default_dict(self):
        assert DataClassMutableDefaultDict().to_json() == '{"xs": {}}'


class TestDecoder:
    def test_list(self):
        assert (DataClassWithList.from_json('{"xs": [1]}') ==
                DataClassWithList([1]))

    def test_list_str(self):
        assert (DataClassWithListStr.from_json('{"xs": ["1"]}') ==
                DataClassWithListStr(["1"]))

    def test_dict(self):
        assert (DataClassWithDict.from_json('{"kvs": {"1": "a"}}') ==
                DataClassWithDict({'1': 'a'}))

    def test_dict_int(self):
        assert (DataClassWithDictInt.from_json('{"kvs": {"1": "a"}}') ==

                DataClassWithDictInt({1: 'a'}))