Example #1
0
def test_mapper_in_list():
    class Foo(Structure):
        a = String
        i = Integer

    class Bar(Structure):
        wrapped = Array[Foo]

    mapper = {'wrapped._mapper': {'a': 'aaa', 'i': 'iii'}, 'wrapped': 'other'}
    deserializer = Deserializer(target_class=Bar, mapper=mapper)
    deserialized = deserializer.deserialize(
        {
            'other': [{
                'aaa': 'string1',
                'iii': 1
            }, {
                'aaa': 'string2',
                'iii': 2
            }]
        },
        keep_undefined=False)

    assert deserialized == Bar(
        wrapped=[Foo(a='string1', i=1),
                 Foo(a='string2', i=2)])
Example #2
0
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]
                               })
Example #3
0
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')
Example #4
0
    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)
Example #5
0
def test_deserializer_no_mapper():
    class Foo(Structure):
        m = Map
        s = String
        i = Integer

    deserializer = Deserializer(target_class=Foo)

    foo = deserializer.deserialize({'m': {'x': 1}, 's': 'abc', 'i': 9999})

    assert foo.i == 9999
Example #6
0
def test_ignore_node_should_not_work_on_required_fields():
    class Foo(Structure):
        a = Integer
        s = String
        i = Integer
        _required = ["s"]
        _ignore_none = True

    with raises(TypeError) as excinfo:
        Deserializer(target_class=Foo).deserialize({
            "s": None,
            "a": None,
            "i": 1
        })
    assert "s: Got None; Expected a string" in str(excinfo.value)
    assert Deserializer(target_class=Foo).deserialize({
        "s": "x",
        "a": None,
        "i": 1
    }).a is None
Example #7
0
def test_convert_camel_case2():
    class Foo(Structure):
        first_name: String
        last_name: String
        age_years: PositiveInt
        _additionalProperties = False

    input_dict = {"first_name": "joe", "last_name": "smith", "ageYears": 5}
    res = Deserializer(target_class=Foo,
                       camel_case_convert=True).deserialize(input_dict)
    assert res == Foo(first_name="joe", last_name="smith", age_years=5)
Example #8
0
def test_enum_deserialization_converts_to_enum():
    class Values(enum.Enum):
        ABC = enum.auto()
        DEF = enum.auto()
        GHI = enum.auto()

    class Example(Structure):
        arr = Array[Enum[Values]]

    deserialized = Deserializer(target_class=Example).deserialize(
        {'arr': ['GHI', 'DEF', 'ABC']})
    assert deserialized.arr == [Values.GHI, Values.DEF, Values.ABC]
Example #9
0
def test_pickle_with_map_without_any_type_definition():
    class Bar(Structure):
        m = Map()
        a = Integer

    original = Bar(a=3, m={'abc': Bar(a=2, m={"x": "xx"}), 'bcd': 2})
    serialized = serialize(original)
    unpickeled = pickle.loads(pickle.dumps(serialized))
    deserialized = Deserializer(target_class=Bar).deserialize(unpickeled)
    # there is no info on the fact that deserialized.m['abc'] should be converted to a Bar instance, so
    # we convert it to a simple dict, to make it straight forward to compare
    original.m['abc'] = Serializer(original.m['abc']).serialize()
    assert deserialized == original
Example #10
0
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]))
Example #11
0
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]))
Example #12
0
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)