def test_union_serializer_plain(): union_s = create_serializer(Union[str, int, float]) assert union_s.serialize('1') == '1' assert union_s.deserialize('1') == '1' assert union_s.serialize(union_s.deserialize('1')) == '1' assert union_s.serialize(1) == 1 assert union_s.deserialize(1) == 1 assert union_s.serialize(union_s.deserialize(1)) == 1 assert union_s.serialize(1.2) == 1.2 assert union_s.deserialize(1.2) == 1.2 assert union_s.serialize(union_s.deserialize(1.2)) == 1.2 with pytest.raises(SerializerError): union_s.serialize([1, 2, 3]) with pytest.raises(SerializerError): union_s.serialize({}) # Optional[int] == Union[int, None] union_s_2 = create_serializer(Optional[str]) assert union_s_2.serialize('1') == '1' assert union_s_2.deserialize('1') == '1' assert union_s_2.serialize(union_s_2.deserialize('1')) == '1' assert union_s_2.serialize(None) is None assert union_s_2.deserialize(None) is None assert union_s_2.serialize(union_s_2.deserialize(None)) is None
def test_before_serializer_exist(): with pytest.raises(SerializerError) as e: create_serializer(User) assert 'serializer class for typing' in str(e.value) assert 'datetime' in str(e.value) assert 'is not defined.' in str(e.value)
def test_after_serializer_defined(): class DatetimeSerializer(Serializer): @staticmethod def test_typing(typing: datetime) -> bool: return typing is datetime def __init__(self, typing, prev_breadcrumbs: str = None): self._init_breadcrumbs('Datetime', prev_breadcrumbs) def _serialize(self, instance: datetime): return instance.isoformat() def _deserialize(self, instance: str) -> datetime: return parse(instance) user_serializer = create_serializer(User) user = User('feleks', '123', datetime.now()) user_serialized = user_serializer.serialize(user) assert isinstance(user_serialized['creation_date'], str) user_deserialized: User = user_serializer.deserialize(user_serialized) assert isinstance(user_deserialized.creation_date, datetime) assert user.creation_date == user_deserialized.creation_date assert user == user_deserialized assert user is not user_deserialized
def test_list_serializer_complex(): list_dict_s = create_serializer(List[Dict[str, float]]) valid_serialized_list_1 = [ { 'a': 1.2, 'b': 1.23 }, { 'c': 5.5, 'd': 3.33 } ] invalid_serialized_dict_1 = [ { 'a': 1.1, 'b': 5 } ] invalid_serialized_dict_2 = [ { 'a': 1.1, 'b': 5.1 }, 33 ] assert list_dict_s.deserialize(valid_serialized_list_1) == valid_serialized_list_1 with pytest.raises(SerializerError): list_dict_s.deserialize(invalid_serialized_dict_1) with pytest.raises(SerializerError): list_dict_s.serialize(invalid_serialized_dict_2)
def test_namedtuple_serializer_plain(): named_tuple_serializer = create_serializer(User) user = User('root', '123') user_serialized = {'login': '******', 'password': '******'} assert named_tuple_serializer.serialize(user) == user_serialized assert named_tuple_serializer.deserialize(user_serialized) == user
def test_none_serializer(): none_s = create_serializer(None) none_t_s = create_serializer(type(None)) assert none_s.serialize(None) is None assert none_s.deserialize(None) is None assert none_s.serialize(none_s.deserialize(None)) is None assert none_t_s.serialize(None) is None assert none_t_s.deserialize(None) is None assert none_t_s.serialize(none_t_s.deserialize(None)) is None with pytest.raises(SerializerError): none_s.serialize(True) with pytest.raises(SerializerError): none_s.deserialize(35)
def test_enum_serializer_complex(): user_s = create_serializer(User) user = User('root', '123', UserRank.admin) user_serialized = {'login': '******', 'password': '******', 'rank': 'admin'} assert user_s.serialize(user) == user_serialized assert user_s.deserialize(user_serialized) == user
def test_enum_serializer_plain(): user_rank_s = create_serializer(UserRank) str_enum_s = create_serializer(StrEnum) assert user_rank_s.serialize(UserRank.admin) == 'admin' assert user_rank_s.serialize(UserRank.user) == 'user' assert user_rank_s.serialize(UserRank.chat_moderator) == 'chat_moderator' assert str_enum_s.serialize(StrEnum.a) == 'a' assert str_enum_s.serialize(StrEnum.b) == 'b' assert str_enum_s.serialize(StrEnum.c) == 'c' assert user_rank_s.deserialize('admin') is UserRank.admin assert user_rank_s.deserialize('user') is UserRank.user assert user_rank_s.deserialize('chat_moderator') is UserRank.chat_moderator assert str_enum_s.deserialize('a') is StrEnum.a assert str_enum_s.deserialize('b') is StrEnum.b assert str_enum_s.deserialize('c') is StrEnum.c
def test_inherited_class(): serializable_class_s = create_serializer(InheritedClass) a = InheritedClass(1) a_s = serializable_class_s.serialize(a) assert a.a == a_s['a'] a_d = serializable_class_s.deserialize(a_s) assert a.a == a_d.a
def test_tuple_serializer_plain(): tuple_s = create_serializer(Tuple[int, str, bool, float]) assert tuple_s.serialize([1, '2', False, 1.1]) == [1, '2', False, 1.1] assert tuple_s.deserialize([1, '2', False, 1.1]) == (1, '2', False, 1.1) assert tuple_s.serialize(tuple_s.deserialize([1, '2', False, 1.1])) == [1, '2', False, 1.1] with pytest.raises(SerializerError): tuple_s.serialize([1, '2', False, 1]) with pytest.raises(SerializerError): tuple_s.serialize([[1, True, False, 1.1]])
def test_str_serializer(): str_s = create_serializer(str) assert str_s.serialize('hello') == 'hello' assert str_s.deserialize('hello') == 'hello' assert str_s.serialize(str_s.deserialize('hello')) == 'hello' with pytest.raises(SerializerError): str_s.serialize(1) with pytest.raises(SerializerError): str_s.deserialize(1)
def test_float_serializer(): float_s = create_serializer(float) assert float_s.serialize(1.1) == 1.1 assert float_s.deserialize(1.1) == 1.1 assert float_s.serialize(float_s.deserialize(1.1)) == 1.1 with pytest.raises(SerializerError): float_s.serialize(1) with pytest.raises(SerializerError): float_s.deserialize(1)
def test_list_serializer(): list_s = create_serializer(list) assert list_s.serialize([1, 2, 3, 'w']) == [1, 2, 3, 'w'] assert list_s.deserialize([1, 2, 3, 'w']) == [1, 2, 3, 'w'] assert list_s.serialize(list_s.deserialize([1, 2, 3, 'w'])) == [1, 2, 3, 'w'] with pytest.raises(SerializerError): list_s.serialize({}) with pytest.raises(SerializerError): list_s.deserialize({1, 2, 3})
def test_tuple_serializer(): tuple_s = create_serializer(tuple) assert tuple_s.serialize((1, 2, 3, 'w')) == (1, 2, 3, 'w') assert tuple_s.deserialize((1, 2, 3, 'w')) == (1, 2, 3, 'w') assert tuple_s.serialize(tuple_s.deserialize( (1, 2, 3, 'w'))) == (1, 2, 3, 'w') with pytest.raises(SerializerError): tuple_s.serialize([1, 2, 3, 4]) with pytest.raises(SerializerError): tuple_s.deserialize({})
def test_dict_serializer_complex(): dict_tuple_list_s = create_serializer(Dict[Tuple[int, int], Tuple[str]]) valid_serialized_dict_1 = {(1, 2): ['1'], (2, 1): ['3'], (0, 0): ['2']} valid_serialized_dict_2 = { (1, 2): ('1', ), (2, 1): ('3', ), (0, 0): ('2', ) } assert dict_tuple_list_s.deserialize(valid_serialized_dict_1) == \ dict_tuple_list_s.deserialize(valid_serialized_dict_2)
def test_complex_class(): user_serializer = create_serializer(User) user_serialized = { 'id': 1, 'login': '******', 'password': '******', 'two_factor_auth': ('3DWR32GS', '9d2fa0ccf73d11e9b740784f439c7d4d') } user: User = user_serializer.deserialize(user_serialized) assert user.two_factor_auth.secret_key == '3DWR32GS' assert user.two_factor_auth.picture_url == '9d2fa0ccf73d11e9b740784f439c7d4d'
def test_list_serializer_plain(): list_int_s = create_serializer(List[int]) assert list_int_s.serialize([1, 2, 3]) == [1, 2, 3] assert list_int_s.deserialize([1, 2, 3]) == [1, 2, 3] # cause isinstance(True, int) == True! (but isinstance(1, bool) == False) assert list_int_s.deserialize([1, 2, 3, True]) == [1, 2, 3, 1] assert list_int_s.serialize(list_int_s.deserialize([1, 2, 3])) == [1, 2, 3] with pytest.raises(SerializerError): list_int_s.serialize([1, 2, 3, '4']) with pytest.raises(SerializerError): list_int_s.serialize([1, 2, 3, 1.1])
def test_simple_class(): serializable_class_s = create_serializer(SerializableClass1) a = SerializableClass1(1, '1') b = SerializableClass1(2, '2') a_s = serializable_class_s.serialize(a) b_s = serializable_class_s.serialize(b) with pytest.raises(SerializerError): serializable_class_error_s = create_serializer(SerializableClass1Error) assert a.a == a_s[0] assert a.b == a_s[1] assert b.a == b_s[0] assert b.b == b_s[1] a_d = serializable_class_s.deserialize(a_s) b_d = serializable_class_s.deserialize(b_s) assert a.a == a_d.a assert a.b == a_d.b assert b.a == b_d.a assert b.b == b_d.b
def test_dataclass_serializer_complex(): user_storage_serializer = create_serializer(UserStorage) user_storage = UserStorage(user_ids=[0, 1], users={ 0: User(0, 'root', '123'), 1: User(1, 'feleks', '228', banned=True, balance_usd=10.0, auth_cnt=322, birth_date='01.06.1996') }, status=UserStorageStatus.synchronized) user_storage_serialized = { 'user_ids': [0, 1], 'users': { 0: { 'id': 0, 'login': '******', 'password': '******', 'banned': False, 'balance_usd': 0.0, 'auth_cnt': 0, 'birth_date': None }, 1: { 'id': 1, 'login': '******', 'password': '******', 'banned': True, 'balance_usd': 10.0, 'auth_cnt': 322, 'birth_date': '01.06.1996', } }, 'status': 'synchronized' } assert user_storage_serializer.serialize( user_storage) == user_storage_serialized assert user_storage_serializer.deserialize( user_storage_serialized) == user_storage
def test_union_serializer_complex(): union_s = create_serializer(Union[User, List[Dict[int, int]]]) assert union_s.serialize(User('root', '123')) == { 'login': '******', 'password': '******' } assert union_s.deserialize({ 'login': '******', 'password': '******' }) == User('root', '123') assert union_s.serialize(union_s.deserialize({'login': '******', 'password': '******'})) == \ {'login': '******', 'password': '******'} assert union_s.serialize([{1: 1}]) == [{1: 1}] assert union_s.deserialize([{1: 1}]) == [{1: 1}] assert union_s.serialize(union_s.deserialize([{1: 1}])) == [{1: 1}]
def test_int_serializer(): int_s = create_serializer(int) assert int_s.serialize(1) == 1 assert int_s.deserialize(1) == 1 assert int_s.serialize(int_s.deserialize(1)) == 1 with pytest.raises(SerializerError): int_s.serialize('q') with pytest.raises(SerializerError): int_s.serialize(1.1) with pytest.raises(SerializerError): int_s.serialize([]) with pytest.raises(SerializerError): int_s.deserialize('q')
def test_dict_serializer(): dict_s = create_serializer(dict) assert dict_s.serialize({'a': {'a': 3}}) == {'a': {'a': 3}} assert dict_s.deserialize({'a': {'a': 3}}) == {'a': {'a': 3}} assert dict_s.serialize(dict_s.deserialize({'a': { 'a': 3 }})) == { 'a': { 'a': 3 } } with pytest.raises(SerializerError): dict_s.serialize([]) with pytest.raises(SerializerError): dict_s.deserialize([])
def test_dict_serializer_plain(): dict_int_str_s = create_serializer(Dict[int, str]) assert dict_int_str_s.serialize({1: '3', 2: '4'}) == {1: '3', 2: '4'} assert dict_int_str_s.deserialize({1: '3', 2: '4'}) == {1: '3', 2: '4'} assert dict_int_str_s.serialize( dict_int_str_s.deserialize({ 1: '3', 2: '4' })) == { 1: '3', 2: '4' } with pytest.raises(SerializerError): dict_int_str_s.serialize({1: False}) with pytest.raises(SerializerError): dict_int_str_s.serialize({'1': '3333'})
def test_user_storage_example(): user_storage_serializer = create_serializer(UserStorage) user_storage_serialized = { 'users': { 1: { 'id': 1, 'login': '******', 'password': '******', 'friend_ids': [2, 3], 'avatar_url': './assets/pepe.png', 'rank': 'user' } }, 'user_location_coordinates': { 1: (1.29485739, 23.232293) }, 'user_additional_attributes': { 1: [{ 'name': 'last_name', 'value': 'George' }, { 'name': 'height_meters', 'value': 1.92 }, { 'name': 'weight_kilos', 'value': 110 }] } } user_storage: UserStorage = user_storage_serializer.deserialize( user_storage_serialized) user = user_storage.get_user_by_login('feleks') assert user.password == '228' assert user_storage.get_user_attribute(user.id, 'last_name') == 'George' assert user_storage.get_user_attribute(user.id, 'height_meters') == 1.92 assert user_storage.get_user_attribute(user.id, 'weight_kilos') == 110 assert user_storage.get_user_location_coordinates(user.id) == (1.29485739, 23.232293)
def test_complex_example_user(): user_serializer = create_serializer(User) user = User(1, 'feleks', '228', UserRank.user, [1, 2, 3]) user_serialized = { 'id': 1, 'login': '******', 'password': '******', 'friend_ids': [1, 2, 3], 'avatar_url': None, 'rank': 'user' } assert user_serializer.serialize(user) == user_serialized assert user_serializer.deserialize(user_serialized) == user assert json.loads(user_serializer.serialize_json(user)) == json.loads( json.dumps(user_serialized)) user_serialized_faulty_1 = { # Id is now str instead if int 'id': '1', 'login': '******', 'password': '******', 'avatar_url': None, 'friend_ids': [1, 2, 3], 'rank': 'user' } user_serialized_faulty_2 = { 'id': 1, 'login': '******', 'password': '******', 'avatar_url': None, # Not all elements of list are int now 'friend_ids': [1, 2, '3'], 'rank': 'user' } user_serialized_faulty_3 = { 'id': 1, 'login': '******', 'password': '******', 'avatar_url': None, 'friend_ids': [1, 2, 3], # There is no such member in UserRank enum 'rank': 'chat_moderator' } with pytest.raises(SerializerError) as e: user_serializer.deserialize(user_serialized_faulty_1) assert 'Validation error. ' \ 'dataclass.User[\'id\']->int: ' \ 'expected type: <class \'int\'>; got <class \'str\'>.' in str(e.value) with pytest.raises(SerializerError) as e: user_serializer.deserialize(user_serialized_faulty_2) assert 'Validation error. ' \ 'dataclass.User[\'friend_ids\']->List[]->int: ' \ 'expected type: <class \'int\'>; got <class \'str\'>.' in str(e.value) with pytest.raises(SerializerError) as e: user_serializer.deserialize(user_serialized_faulty_3) assert 'Invalid enum member \'chat_moderator\', allowed members: [\'user\', \'admin\'].' in str( e.value)
def test_tuple_serializer_complex(): tuple_s = create_serializer(List[Tuple[User, Dict[str, str]]]) data = [ ( User('root', '228'), { 'rank': 'admin' } ), ( User('solo', '322'), { 'rank': 'user' } ) ] data_s = [ [ { 'login': '******', 'password': '******' }, { 'rank': 'admin' } ], [ { 'login': '******', 'password': '******' }, { 'rank': 'user' } ] ] assert tuple_s.serialize(data) == data_s assert tuple_s.deserialize(data_s) == data data_d = tuple_s.deserialize(data_s) assert isinstance(data_d[0][0], User) assert isinstance(data_d[1][0], User) assert isinstance(data_d[0][1], dict) assert isinstance(data_d[1][1], dict) assert data_d[0][0].login == 'root' assert data_d[0][0].password == '228' assert data_d[1][0].login == 'solo' assert data_d[1][0].password == '322' assert data_d[0][1]['rank'] == 'admin' assert data_d[1][1]['rank'] == 'user' serialized_tuple_error_1 = [ [ { 'login': '******', 'password': '******' }, { 'rank': 1 } ] ] serialized_tuple_error_2 = [ [ { 'login': '******', 'password': '******' }, False ] ] with pytest.raises(SerializerError): tuple_s.deserialize(serialized_tuple_error_1) with pytest.raises(SerializerError): tuple_s.deserialize(serialized_tuple_error_2)
def test_wrong_class(): with pytest.raises(SerializerError): create_serializer(WrongClass)
def test_dataclass_serializer_plain(): user_1 = User(0, 'root', '123') user_2 = User(None, 'feleks', '228', banned=True, balance_usd=10.0, auth_cnt=322, birth_date='01.06.1996') user_1_serialized = { 'id': 0, 'login': '******', 'password': '******', 'banned': False, 'balance_usd': 0.0, 'auth_cnt': 0, 'birth_date': None } user_2_serialized = { 'id': None, 'login': '******', 'password': '******', 'banned': True, 'balance_usd': 10.0, 'auth_cnt': 322, 'birth_date': '01.06.1996' } user_serializer = create_serializer(User) assert user_serializer.serialize(user_1) == user_1_serialized assert user_serializer.deserialize(user_1_serialized) == user_1 assert user_serializer.serialize(user_2) == user_2_serialized assert user_serializer.deserialize(user_2_serialized) == user_2 with pytest.raises(SerializerError): user_serializer.deserialize({ 'id': 0, 'login': '******', # Password is not Optional. 'password': None, 'banned': False, 'balance_usd': 0.0, 'auth_cnt': 0, 'birth_date': None }) with pytest.raises(SerializerError): user_serializer.deserialize({ 'id': 0, # Missing non-default field 'login'. 'password': '******', 'banned': False, 'balance_usd': 0.0, 'auth_cnt': 0, 'birth_date': None }) with pytest.raises(SerializerError): user_serializer.deserialize({ # Missing id field (id is Optional (=nullable), but it has no default value). 'login': '******', 'password': '******', 'banned': False, 'balance_usd': 0.0, 'auth_cnt': 0, 'birth_date': None })