def test_bad_path_in_mapper(): class Foo(Structure): m = Map s = String i = Integer mapper = { "m": "a.x", "s": FunctionCall(func=lambda x: x, args=['name']), 'i': FunctionCall(func=operator.add, args=['i', 'j']) } with raises(TypeError) as excinfo: deserialize_structure(Foo, { 'a': { 'b': { 'x': 1, 'y': 2 } }, 'name': { 'first': 'Joe', 'last': 'smith' }, 'i': 3, 'j': 4 }, mapper=mapper, keep_undefined=False) assert "m: Got None; Expected a dictionary" in str(excinfo.value)
def test_mapper_variation_3(): class Foo(Structure): m = Map s = String i = Integer mapper = { "m": "a.b", "s": FunctionCall(func=lambda x: f'the string is {x}'), 'i': FunctionCall(func=lambda x: x * 2) } foo = deserialize_structure(Foo, { 'a': { 'b': { 'x': 1, 'y': 2 } }, 's': 'Joe', 'i': 3 }, mapper=mapper, keep_undefined=False) assert foo == Foo(i=6, m={'x': 1, 'y': 2}, s='the string is Joe')
def test_invalid_mapper_value(): class Foo(Structure): m = Map s = String i = Integer mapper = { "m": 5, "s": FunctionCall(func=lambda x: x, args=['name']), 'i': FunctionCall(func=operator.add, args=['i', 'j']) } with raises(TypeError) as excinfo: deserialize_structure(Foo, { 'a': { 'b': { 'x': 1, 'y': 2 } }, 'name': { 'first': 'Joe', 'last': 'smith' }, 'i': 3, 'j': 4 }, mapper=mapper, keep_undefined=False) assert "mapper value must be a key in the input or a FunctionCal. Got 5" in str( excinfo.value)
def test_valid_deserializer(): class Foo(Structure): m = Map s = String i = Integer mapper = { "m": "a.b", "s": FunctionCall(func=lambda x: f'the string is {x}', args=['name.first']), 'i': FunctionCall(func=operator.add, args=['i', 'j']) } deserializer = Deserializer(target_class=Foo, mapper=mapper) foo = deserializer.deserialize( { 'a': { 'b': { 'x': 1, 'y': 2 } }, 'name': { 'first': 'Joe', 'last': 'smith' }, 'i': 3, 'j': 4 }, keep_undefined=False) assert foo == Foo(i=7, m={'x': 1, 'y': 2}, s='the string is Joe')
def transform_foo_to_bar(foo: Foo) -> Bar: mapper = { 'i': FunctionCall(func=lambda f: [int(f)], args=['i']), 'f': FunctionCall(func=lambda x: str(x), args=['f']) } deserializer = Deserializer(Bar, {'numbers': 'i', 's': 'f'}) serializer = Serializer(source=foo, mapper=mapper) return deserializer.deserialize(serializer.serialize(), keep_undefined=False)
def test_serialize_with_mapper_with_function_with_args(): class Foo(Structure): f = Float i = Integer foo = Foo(f=5.5, i=999) mapper = { 'f': FunctionCall(func=lambda f: [int(f)], args=['i']), 'i': FunctionCall(func=lambda x: str(x), args=['f']) } assert serialize(foo, mapper=mapper) == {'f': [999], 'i': '5.5'}
def test_serialize_with_mapper_with_function_converting_types(): class Foo(Structure): num = Float i = Integer foo = Foo(num=5.5, i=999) mapper = { 'num': FunctionCall(func=lambda f: [int(f)]), 'i': FunctionCall(func=lambda x: str(x)) } assert serialize(foo, mapper=mapper) == {'num': [5], 'i': '999'}
def test_serializer_with_invalid_mapper_key_type(): class Foo(Structure): f = Float i = Integer foo = Foo(f=5.5, i=999) mapper = { 123: FunctionCall(func=lambda f: [int(f)], args=['i']), 'i': FunctionCall(func=lambda x: str(x), args=['f']) } with raises(TypeError) as excinfo: Serializer(foo, mapper=mapper) assert 'mapper_key: Got 123; Expected a string' in str(excinfo.value)
def test_serialize_with_mapper_with_functions(): def my_func(): pass class Foo(Structure): function = Function i = Integer foo = Foo(function=my_func, i=1) mapper = { 'function': FunctionCall(func=lambda f: f.__name__), 'i': FunctionCall(func=lambda x: x + 5) } assert serialize(foo, mapper=mapper) == {'function': 'my_func', 'i': 6}
def test_serializer_with_invalid_function_call_arg(): class Foo(Structure): f = Float i = Integer foo = Foo(f=5.5, i=999) mapper = { 'f': FunctionCall(func=lambda f: [int(f)], args=['i', 'x']), 'i': FunctionCall(func=lambda x: str(x), args=['f']) } with raises(ValueError) as excinfo: Serializer(foo, mapper=mapper) assert 'Mapper[f] has a function call with an invalid argument: x' in str( excinfo.value)
def test_serializer_with_invalid_mapper_key(): class Foo(Structure): f = Float i = Integer foo = Foo(f=5.5, i=999) mapper = { 'x': FunctionCall(func=lambda f: [int(f)], args=['i']), 'i': FunctionCall(func=lambda x: str(x), args=['f']) } with raises(ValueError) as excinfo: Serializer(foo, mapper=mapper) assert 'Invalid key in mapper for class Foo: x. Keys must be one of the class fields.' in str( excinfo.value)
def test_serialize_with_deep_mapper(): class Foo(Structure): a = String i = Integer class Bar(Structure): foo = Foo array = Array class Example(Structure): bar = Bar number = Integer example = Example(number=1, bar=Bar(foo=Foo(a="string", i=5), array=[1, 2])) mapper = { 'bar._mapper': { 'foo._mapper': { "i": FunctionCall(func=lambda x: x * 2) } } } serialized = serialize(example, mapper=mapper) assert serialized == \ { "number": 1, "bar": { "foo": { "a": "string", "i": 10 }, "array": [1, 2] } }
def test_mapper_in_embedded_structure(): class Foo(Structure): a = String i = Integer s = StructureReference(st=String, arr=Array) mapper = { 'a': 'aaa', 'i': 'iii', 's._mapper': { "arr": FunctionCall(func=lambda x: x * 2, args=['xxx']) } } deserializer = Deserializer(target_class=Foo, mapper=mapper) deserialized = deserializer.deserialize( { 'aaa': 'string', 'iii': 1, 's': { 'st': 'string', 'xxx': [1, 2, 3] } }, keep_undefined=False) assert deserialized == Foo(a='string', i=1, s={ 'st': 'string', 'arr': [1, 2, 3, 1, 2, 3] })
def test_invalid_deserializer(): class Foo(Structure): m = Map s = String i = Integer mapper = { "xyz": "a.b", "s": FunctionCall(func=lambda x: f'the string is {x}', args=['name.first']), 'i': FunctionCall(func=operator.add, args=['i', 'j']) } with raises(ValueError) as excinfo: Deserializer(target_class=Foo, mapper=mapper) assert "Invalid key in mapper for class Foo: xyz. Keys must be one of the class fields" in str( excinfo.value)
def test_serializer_with_invalid_mapper_value_type(): class Foo(Structure): f = Float i = Integer foo = Foo(f=5.5, i=999) mapper = {'f': 123, 'i': FunctionCall(func=lambda x: str(x), args=['f'])} with raises(ValueError) as excinfo: Serializer(foo, mapper=mapper) assert 'mapper_value: Got 123; Did not match any field option' in str( excinfo.value)
def test_serialize_with_mapper_error(): def my_func(): pass class Foo(Structure): function = Function i = Integer foo = Foo(function=my_func, i=1) mapper = {'function': 5, 'i': FunctionCall(func=lambda x: x + 5)} with raises(TypeError) as excinfo: serialize(foo, mapper=mapper) assert 'mapper must have a FunctionCall or a string' in str(excinfo.value)
def test_serialize_with_deep_mapper_camel_case(): class Foo(Structure): a = String i_num = Integer c_d = Integer class Bar(Structure): foo_bar = Foo array_one = Array class Example(Structure): bar = Bar number = Integer example = Example(number=1, bar=Bar(foo_bar=Foo(a="string", i_num=5, c_d=2), array_one=[1, 2])) mapper = { 'bar._mapper': { 'foo_bar._mapper': { "c_d": "cccc", "i_num": FunctionCall(func=lambda x: x * 2) } } } serialized = serialize(example, mapper=mapper, camel_case_convert=True) assert serialized == \ { "number": 1, "bar": { "fooBar": { "a": "string", "iNum": 10, "cccc": 2 }, "arrayOne": [1, 2] } }
def test_deserialize_with_deep_mapper_camel_case(): class Foo(Structure): a_b = String i = Integer class Bar(Structure): foo_bar = Foo array_nums = Array class Example(Structure): bar = Bar number = Integer mapper = { 'bar._mapper': { 'fooBar._mapper': { "i": FunctionCall(func=lambda x: x * 2) } } } deserializer = Deserializer(target_class=Example, mapper=mapper, camel_case_convert=True) deserialized = deserializer.deserialize( { "number": 1, "bar": { "fooBar": { "aB": "string", "i": 10 }, "arrayNums": [1, 2] } }, keep_undefined=False) assert deserialized == Example(number=1, bar=Bar(foo_bar=Foo(a_b="string", i=20), array_nums=[1, 2]))
def test_mapper_variation_1(): class Foo(Structure): m = Map s = String i = Integer mapper = { "m": "a", "s": FunctionCall(func=lambda x: f'the string is {x}', args=['name']) } foo = deserialize_structure(Foo, { 'a': { 'a': 1, 'b': [1, 2, 3] }, 'name': 'Joe', 'i': 3 }, mapper=mapper, keep_undefined=False) assert foo == Foo(i=3, m={'a': 1, 'b': [1, 2, 3]}, s='the string is Joe')
def test_deserialize_with_deep_mapper(): class Foo(Structure): a = String i = Integer class Bar(Structure): foo = Foo array = Array class Example(Structure): bar = Bar number = Integer mapper = { 'bar._mapper': { 'foo._mapper': { "i": FunctionCall(func=lambda x: x * 2) } } } deserializer = Deserializer(target_class=Example, mapper=mapper) deserialized = deserializer.deserialize( { "number": 1, "bar": { "foo": { "a": "string", "i": 10 }, "array": [1, 2] } }, keep_undefined=False) assert deserialized == Example(number=1, bar=Bar(foo=Foo(a="string", i=20), array=[1, 2]))