Exemple #1
0
def test_only_union():
    from attrkid import to_dict
    from attrkid.fields import (
        list_field,
        object_field,
        string_field,
    )
    from attrkid.kind import UnionKind

    @attr.s
    class Value:
        value = string_field()

    @attr.s
    class And:
        items = list_field(Value, is_only_field=True)

    @attr.s
    class Not:
        item = object_field(Value, is_only_field=True)

    @attr.s
    class Container:
        expr = object_field(UnionKind(('and', And), ('not', Not)))

    c1 = Container(expr=And(items=[Value('hello'), Value('world')]))
    c2 = Container(expr=Not(item=Value('boo')))

    expected_c1 = {'expr': {'and': [{'value': 'hello'}, {'value': 'world'}]}}
    assert expected_c1 == to_dict(c1)

    expected_c2 = {'expr': {'not': {'value': 'boo'}}}
    assert expected_c2 == to_dict(c2)
Exemple #2
0
def test_only_field():
    from attrkid import from_dict, to_dict
    from attrkid.fields import (
        list_field,
        object_field,
        string_field,
    )

    @attr.s
    class Value:
        value = string_field()

    @attr.s
    class Not:
        item = object_field(Value, is_only_field=True)

    @attr.s
    class And:
        items = list_field(Value, is_only_field=True)

    n = Not(item=Value(value='boo'))
    expected_n = {'value': 'boo'}
    assert expected_n == to_dict(n)
    assert n == from_dict(Not, expected_n)

    a = And(items=[Value(value='hello'), Value(value='world')])
    expected_a = [{'value': 'hello'}, {'value': 'world'}]
    assert expected_a == to_dict(a)
    assert a == from_dict(And, expected_a)
Exemple #3
0
def test_to_dict(dt):
    from attrkid import to_dict, from_dict
    from attrkid.fields import datetime_field, list_field
    from attrkid.options import SerdeOptions

    @attr.s
    class X:
        f = attr.ib()

    @attr.s
    class M:
        s = attr.ib(validator=instance_of(str))
        i = attr.ib(validator=instance_of(int))
        nullable = attr.ib()
        d = datetime_field()
        lst1 = list_field(int)
        lst2 = list_field(X)

    m = M(
        s='hello',
        i=42,
        d=dt,
        lst1=[1, 2, 3],
        lst2=[X(f=1)],
        nullable=None,
    )
    options = SerdeOptions(omit_null_values=False)
    actual = to_dict(m, options=options)
    expected = {
        's': 'hello',
        'i': 42,
        'd': '2017-11-13T15:12:00.000000Z',
        'lst1': [1, 2, 3],
        'lst2': [{
            'f': 1
        }],
        'nullable': None
    }
    assert expected == actual

    expected_nullable = {
        's': 'hello',
        'i': 42,
        'd': '2017-11-13T15:12:00.000000Z',
        'lst1': [1, 2, 3],
        'lst2': [{
            'f': 1
        }],
    }
    actual_nullable = to_dict(m)
    assert expected_nullable == actual_nullable

    # Check we can round-trip
    m1 = from_dict(M, actual)
    assert m == m1

    m2 = from_dict(M, actual_nullable)
    assert m == m2
Exemple #4
0
def test_datetime_custom_serialisation(dt):
    from attrkid import to_dict
    from attrkid.fields import datetime_field
    from attrkid.options import SerdeOptions

    @attr.s
    class M:
        f = datetime_field()

    m = M(f=dt)
    assert {'f': '2017-11-13T15:12:00.000000Z'} == to_dict(m)
    options = SerdeOptions(datetime_format='%Y')
    assert {'f': '2017'} == to_dict(m, options=options)
Exemple #5
0
def test_tuple_of_union():
    from attrkid import to_dict, from_dict
    from attrkid.fields import string_field, tuple_field
    from attrkid.kind import UnionKind

    @attr.s(hash=True)
    class A:
        f = string_field()

    @attr.s(hash=True)
    class B:
        f = string_field()

    @attr.s(hash=True)
    class C:
        t = tuple_field(UnionKind(
            ('a', A),
            ('b', B),
        ))

    # Check we can round-trip
    a = A(f='a')
    b = B(f='b')
    c = C(t=(a, b))
    as_dict = to_dict(c)
    as_ob = from_dict(C, as_dict)
    assert c == as_ob
Exemple #6
0
def test_default_from_attr():
    from attrkid import from_dict, to_dict
    from attrkid.fields import string_field, set_field

    @attr.s
    class M:
        f = string_field(default_from_attr='_f')
        s = set_field(str, default_from_attr='_s')

        @property
        def _f(self):
            return 'hello'

        @property
        def _s(self):
            return {'hey'}

    m = M()
    assert 'hello' == m.f
    assert {'hey'} == m.s

    expected = {'f': 'hello', 's': ['hey']}
    assert expected == to_dict(m)

    # default_from_attr only provides defaults
    inp = {'f': 'something', 's': ['different']}
    actual = from_dict(M, inp)
    assert M(f='something', s={'different'}) == actual
Exemple #7
0
def test_union_field():
    from attrkid import to_dict, from_dict
    from attrkid.fields import (
        bool_field,
        list_field,
        object_field,
    )
    from attrkid.kind import UnionKind

    @attr.s
    class Value:
        value = bool_field()

    @attr.s
    class And:
        items = list_field(Value)

    @attr.s
    class Not:
        item = object_field(Value)

    @attr.s
    class Container:
        item = object_field(UnionKind(('and', And), ('not', Not)))

    c1 = Container(item=And(items=[Value(value=True), Value(value=False)]))
    expected_c1 = {
        'item': {
            'and': {
                'items': [{
                    'value': True
                }, {
                    'value': False
                }],
            }
        }
    }
    actual_c1 = to_dict(c1)
    assert expected_c1 == actual_c1

    c2 = Container(item=Not(item=Value(value=True)))
    expected_c2 = {'item': {'not': {'item': {'value': True}}}}
    actual_c2 = to_dict(c2)
    assert expected_c2 == actual_c2

    assert c1 == from_dict(Container, actual_c1)
    assert c2 == from_dict(Container, actual_c2)
Exemple #8
0
def test_int_field():
    from attrkid import from_dict, to_dict
    from attrkid.fields import int_field

    @attr.s
    class M:
        n = int_field()

    x = M(n=5)
    assert x == from_dict(M, to_dict(x))
Exemple #9
0
def test_tuple_field_self():
    from attrkid import from_dict, to_dict
    from attrkid.fields import tuple_field
    from attrkid.constants import SELF

    @attr.s
    class MTuple:
        as_tuple = tuple_field(SELF)

    m5 = MTuple()
    m6 = MTuple(as_tuple=(m5, ))
    assert m6 == from_dict(MTuple, to_dict(m6))
Exemple #10
0
def test_list_fields_self():
    from attrkid import to_dict, from_dict
    from attrkid.fields import list_field
    from attrkid.constants import SELF

    @attr.s
    class MList:
        as_list = list_field(SELF)

    m1 = MList()
    m2 = MList(as_list=[m1], )
    assert m2 == from_dict(MList, to_dict(m2))
Exemple #11
0
def test_decimal_field():
    from attrkid import to_dict, from_dict
    from attrkid.fields import decimal_field

    @attr.s
    class M:
        f = decimal_field(prec=5)

    m = M(f=decimal.Decimal('3.4'))
    as_dict = to_dict(m)
    expected = {'f': '3.4'}
    assert expected == as_dict
    as_ob = from_dict(M, as_dict)
    assert m == as_ob
Exemple #12
0
def test_non_serialisable():
    from attrkid import from_dict, to_dict
    from attrkid.fields import string_field

    @attr.s
    class M:
        a = string_field()
        b = string_field(should_serialise=False)

    m = M(a='a', b='b')
    expected = {'a': 'a'}
    assert expected == to_dict(m)
    m2 = from_dict(M, expected)
    assert 'a' == m2.a
    assert m2.b is None
Exemple #13
0
def test_set_field_object():
    from attrkid import from_dict, to_dict
    from attrkid.fields import set_field, int_field

    @attr.s(slots=True, frozen=True, hash=True)
    class A:
        f = int_field()

    @attr.s
    class M:
        xs = set_field(A)

    m = M(xs={A(f=3)})
    d = to_dict(m)
    assert m == from_dict(M, d)
Exemple #14
0
def test_set_field_self():
    from attrkid import from_dict, to_dict
    from attrkid.fields import set_field
    from attrkid.constants import SELF

    @attr.s(hash=True)
    class MSet:
        as_set = set_field(SELF)

    m3 = MSet()
    m4 = MSet(as_set={m3})
    expected_dict = {'as_set': [{'as_set': []}]}
    as_dict = to_dict(m4)
    assert expected_dict == as_dict
    assert m4 == from_dict(MSet, as_dict)
Exemple #15
0
def test_object_field():
    from attrkid import to_dict, from_dict
    from attrkid.fields import object_field

    @attr.s
    class X:
        f = attr.ib()

    @attr.s
    class M:
        f = object_field(X)

    m = M(f=X(f=1))
    expected = {'f': {'f': 1}}
    assert expected == to_dict(m)

    loaded = from_dict(M, expected)
    assert m == loaded
Exemple #16
0
def test_object_field_self():
    from attrkid import to_dict, from_dict
    from attrkid.constants import SELF
    from attrkid.fields import object_field
    from attrkid.options import SerdeOptions

    @attr.s
    class M:
        f = object_field(SELF, is_optional=True)

    m = M(f=M(f=None))
    expected = {'f': {}}

    options = SerdeOptions(omit_null_values=True)
    assert expected == to_dict(m, options=options)

    loaded = from_dict(M, expected)
    assert m == loaded
Exemple #17
0
def test_optional_tuple_field():
    from attrkid import to_dict, from_dict
    from attrkid.fields import tuple_field

    @attr.s
    class X:
        pass

    @attr.s
    class M:
        f = tuple_field(X, is_optional=True, default=None)

    m = M()
    n = M(f=None)
    assert m == n

    as_dict = to_dict(m)
    assert m == from_dict(M, as_dict)

    data = {}
    assert m == from_dict(M, data)
Exemple #18
0
def test_list_of_union_kind():
    from attrkid import to_dict
    from attrkid.fields import list_field, string_field
    from attrkid.kind import UnionKind

    @attr.s
    class V1:
        a = string_field()

    @attr.s
    class V2:
        b = string_field()

    @attr.s
    class M:
        v = list_field(UnionKind(('v1', V1), ('v2', V2)), is_only_field=True)

    m = M(v=[V1(a='hello'), V2(b='world')])
    actual = to_dict(m)
    expected = [{'v1': {'a': 'hello'}}, {'v2': {'b': 'world'}}]
    assert expected == actual
Exemple #19
0
def test_to_dict_nested_flags(dt):
    """
    When a sub-model has a datetime, and to_dict is called with
    convert_datetimes=False, make sure that the datetimes are indeed left
    alone. Same for None/null values - `convert_datetimes` and
    `omit_null_values` should be propagated.
    """
    from attrkid import to_dict
    from attrkid.fields import object_field, datetime_field
    from attrkid.constants import SELF
    from attrkid.options import SerdeOptions

    @attr.s
    class M:
        dt = datetime_field()
        sub = object_field(SELF, is_optional=True, default=None)

    m = M(dt=dt, sub=M(dt=dt))
    expected = {'dt': dt, 'sub': {'dt': dt, 'sub': None}}
    options = SerdeOptions(convert_datetimes=False, omit_null_values=False)
    actual = to_dict(m, options=options)
    assert expected == actual
Exemple #20
0
def test_union_field_deferred(mocker):
    from attrkid import from_dict, to_dict
    from attrkid.fields import object_field
    from attrkid.kind import DeferredKind, UnionKind

    import_module = mocker.patch('importlib.import_module')
    import_module.return_value = sys.modules[__name__]

    selector_for = mocker.patch('attrkid.kind.UnionKind.selector_for')
    selector_for.return_value = 'target'

    @attr.s
    class M:
        m = object_field(
            UnionKind(
                ('target', DeferredKind('tests.test_models.TargetModel')), ))

    m = M(m=TargetModel())
    import_module.assert_called_with('tests.test_models')
    as_dict = to_dict(m)
    selector_for.assert_called_with(TargetModel)
    assert m == from_dict(M, as_dict)