Ejemplo n.º 1
0
def test_union():
    data = {"node": {"name": "n1", "value": "v1"}}
    node = from_dict(NodeWithUnion, data, fd_check_types=True)
    assert isinstance(node.node, SimpleNode)
    assert node.node.name == "n1"
    assert node.node.value == "v1"

    data = {"node": {"name": "n1", "reference": "node-X"}}
    node = from_dict(NodeWithUnion, data, fd_check_types=True)
    assert isinstance(node.node, SimpleNode2)
    assert node.node.name == "n1"
    assert node.node.reference == "node-X"

    data = {"node": {"name": "n1", "no_match": "node-X"}}
    node = from_dict(NodeWithUnion, data)
    assert isinstance(node.node, dict)
    assert node.node["name"] == "n1"
    assert node.node["no_match"] == "node-X"

    data = {"node": {"name": "n1", "no_match": "node-X"}}
    with pytest.raises(TypeError) as e:
        node = from_dict(NodeWithUnion, data, fd_check_types=True)
    assert str(e.value) == (
        'For "node", expected typing.Union[test_generics_with_dataclasses.SimpleNode, '
        'test_generics_with_dataclasses.SimpleNode2] but found <class \'dict\'>'
    )
Ejemplo n.º 2
0
def test_union_works():
    @attr.s(auto_attribs=True)
    class UClass:
        a: Union[str, int]

    assert from_dict(UClass, {"a": "hello"}, fd_check_types=True).a == "hello"
    assert from_dict(UClass, {"a": 22}, fd_check_types=True).a == 22
Ejemplo n.º 3
0
def test_subscripted_attr_generics_work():
    @attr.s(auto_attribs=True)
    class KDict:
        a: int
        b: Optional[str]
        c: List[int]

    opt = from_dict(KDict, a=11, b=None, c=[1, 2, 3])

    assert opt.a == 11
    assert opt.b is None
    assert opt.c == [1, 2, 3]
    assert from_dict(KDict, a=11, b="hi", c=[1, 2, 3]).b == "hi"
Ejemplo n.º 4
0
def test_additional_keys_are_allowed(structures: Structures):
    my_obj = from_dict(structures.inner_structure, foo=22, bar="Works", additional=[1, 2, 3], fd_global_ns=GLOBALS)
    assert my_obj.foo == 22
    assert my_obj.bar == "Works"

    if structures.has_dict:
        assert my_obj.additional == [1, 2, 3]
Ejemplo n.º 5
0
def test_readme():
    customer = from_dict(Customer, input_customer_data)
    # Structured data is available as attributes since attr.s exposes them like that
    assert customer.name == "Christopher Lee"
    # Nested structures are also constructed. List[sub_strucutre] and Dict[key, sub_structure] are supported
    assert customer.preferences[0].name == "The Hobbit"
    # Data not defined in the strucutre is inserted into the __dict__ if possible
    assert customer.__dict__["friend"] == "Mellon"
Ejemplo n.º 6
0
def test_self_ref_in_optional():
    data = {"name": "n1", "next": {"name": "n2", "next": None}}
    node = from_dict(LinkListNode2,
                     data,
                     fd_check_types=True,
                     fd_global_ns=GLOBALS)
    assert node.name == "n1"
    assert node.next.name == "n2"
def test_local_self_ref():
    @dataclass
    class Node:
        name: str
        next: 'Node'

    data = {"name": "n1", "next": {"name": "n2", "next": None}}
    node = from_dict(Node, data, fd_local_ns=locals())
    assert node.name == "n1"
    assert node.next.name == "n2"
def test_local_self_ref_in_optional():
    @dataclass
    class Node:
        name: str
        next: Optional['Node']

    data = {"name": "n1", "next": {"name": "n2", "next": None}}
    node = from_dict(Node, data, fd_check_types=True, fd_local_ns=locals())
    assert node.name == "n1"
    assert node.next.name == "n2"
def test_local_self_ref_in_list():
    @dataclass
    class Node:
        name: str
        children: LIST['Node']

    data = {"name": "n1", "children": [{"name": "n2", "children": []}]}
    node = from_dict(Node, data, fd_check_types=True, fd_local_ns=locals())
    assert node.name == "n1"
    assert node.children[0].name == "n2"
Ejemplo n.º 10
0
def test_union_with_builtin_type():
    data = {"node": {"name": "n1", "value": "v1"}}
    node = from_dict(NodeWithUnionWithBuiltInType, data, fd_check_types=True)
    assert isinstance(node.node, SimpleNode)
    assert node.node.name == "n1"
    assert node.node.value == "v1"

    data = {"node": "Hello"}
    node = from_dict(NodeWithUnionWithBuiltInType, data, fd_check_types=True)
    assert isinstance(node.node, str)
    assert node.node == "Hello"

    data = {"node": {"name": "n1", "no_match": "node-X"}}
    node = from_dict(NodeWithUnionWithBuiltInType, data)
    assert isinstance(node.node, dict)
    assert node.node["name"] == "n1"
    assert node.node["no_match"] == "node-X"

    data = {"node": {"name": "n1", "no_match": "node-X"}}
    with pytest.raises(FromDictTypeError) as e:
        from_dict(NodeWithUnionWithBuiltInType, data, fd_check_types=True)
    assert str(
        e.value
    ) == 'For "node", expected typing.Union[test_generics_with_dataclasses.SimpleNode, str] but found <class \'dict\'>'

    data = {"node": 123}
    with pytest.raises(FromDictTypeError) as e:
        node = from_dict(NodeWithUnionWithBuiltInType,
                         data,
                         fd_check_types=True)
    assert str(
        e.value
    ) == 'For "node", expected typing.Union[test_generics_with_dataclasses.SimpleNode, str] but found <class \'int\'>'
Ejemplo n.º 11
0
def test_dict_with_substructure(structures: Structures):
    @attr.s(auto_attribs=True)
    class SubDict:
        a: Dict[int, structures.inner_structure]

    val = {
        "a": {
            11: {"foo": 11, "bar": "Hi"},
            13: {"foo": 13, "bar": "Sup"},
            -4: {"foo": -4, "bar": "Ya"},
        }
    }
    structs = from_dict(SubDict, val, fd_check_types=not structures.does_type_validation)
    assert all(k == v.foo for k, v in structs.a.items())
Ejemplo n.º 12
0
def test_packing(structures: Structures):
    input_dict = {
        "foo": 22,
        "baz": {
            "foo": 42,
            "bar": "Works :)",
        }
    }

    main_object = from_dict(structures.outer_structure, input_dict, fd_global_ns=GLOBALS)

    assert main_object.baz.bar == "Works :)"
    assert isinstance(main_object, structures.outer_structure)
    assert isinstance(main_object.baz, structures.inner_structure)
Ejemplo n.º 13
0
def test_list_of_structures_work(structures: Structures):
    @attr.s(auto_attribs=True)
    class KList:
        a: List[structures.inner_structure]

    val = {
        "a": [
            {"foo": 11, "bar": "Hi"},
            {"foo": 13, "bar": "Sup"},
            {"foo": -4, "bar": "Ya"},
        ]
    }
    structs = from_dict(KList, val, fd_check_types=not structures.does_type_validation)

    assert structs.a[0].foo == 11
    assert [el.foo for el in structs.a] == [11, 13, -4]
    assert [el.bar for el in structs.a] == ["Hi", "Sup", "Ya"]
Ejemplo n.º 14
0
def test_self_ref_in_dict():
    data = {
        "name": "n1",
        "children": {
            "id-123": {
                "name": "n2",
                "children": {}
            },
            "id-456": {
                "name": "n3",
                "children": {}
            }
        }
    }
    node = from_dict(DictNode, data, fd_check_types=True, fd_global_ns=GLOBALS)
    assert node.name == "n1"
    assert node.children["id-123"].name == "n2"
    assert node.children["id-456"].name == "n3"
def test_local_self_ref_in_dict():
    @dataclass
    class Node:
        name: str
        children: Dict[str, 'Node']

    data = {
        "name": "n1",
        "children": {
            "id-123": {
                "name": "n2",
                "children": {}
            },
            "id-456": {
                "name": "n3",
                "children": {}
            }
        }
    }
    node = from_dict(Node, data, fd_check_types=True, fd_local_ns=locals())
    assert node.name == "n1"
    assert node.children["id-123"].name == "n2"
    assert node.children["id-456"].name == "n3"
Ejemplo n.º 16
0
def test_invalid_type_inherent(structures: Structures):
    if not structures.does_type_validation:
        pytest.skip("Structure does not support inherent runtime type checking")

    with pytest.raises(TypeError) as e:
        from_dict(structures.inner_structure, {"foo": "wrong", "bar": "right"}, fd_check_types=True)
Ejemplo n.º 17
0
def test_missing_key_discovered_in_subdict_inherent(structures: Structures):
    if not structures.does_type_validation:
        pytest.skip("Structure does not support inherent runtime type checking")

    with pytest.raises(TypeError):
        from_dict(structures.outer_structure, {"foo": 22, "baz": {"foo": 42}})
Ejemplo n.º 18
0
def test_self_ref_in_list():
    data = {"name": "n1", "children": [{"name": "n2", "children": []}]}
    node = from_dict(TreeNode, data, fd_check_types=True, fd_global_ns=GLOBALS)
    assert node.name == "n1"
    assert node.children[0].name == "n2"
Ejemplo n.º 19
0
def test_self_ref():
    data = {"name": "n1", "next": {"name": "n2", "next": None}}
    # Can't type check because next is not optional
    node = from_dict(LinkListNode, data, fd_global_ns=GLOBALS)
    assert node.name == "n1"
    assert node.next.name == "n2"
Ejemplo n.º 20
0
def test_optional():
    data = {
        "node1": {
            "name": "n1",
            "value": "v1"
        },
        "node2": {
            "name": "n2",
            "value": "v2"
        },
        "node3": {
            "name": "n3",
            "value": "v3"
        },
    }
    node = from_dict(NodeWithOptional, data, fd_check_types=True)
    assert node.node1.name == "n1"
    assert node.node1.value == "v1"
    assert node.node2.name == "n2"
    assert node.node2.value == "v2"
    assert node.node3.name == "n3"
    assert node.node3.value == "v3"

    data = {
        "node1": {
            "name": "n1",
            "value": "v1"
        },
        "node2": {
            "name": "n2",
            "value": "v2"
        }
    }
    node = from_dict(NodeWithOptional, data, fd_check_types=True)
    assert node.node1.name == "n1"
    assert node.node1.value == "v1"
    assert node.node2.name == "n2"
    assert node.node2.value == "v2"
    assert node.node3 == None

    data = {"node1": {"name": "n1", "value": "v1"}, "node2": None}
    node = from_dict(NodeWithOptional, data, fd_check_types=True)
    assert node.node1.name == "n1"
    assert node.node1.value == "v1"
    assert node.node2 == None
    assert node.node3 == None
    data = {
        "node1": {
            "name": "n1",
            "value": "v1"
        },
        "node2": None,
        "node3": None
    }
    node = from_dict(NodeWithOptional, data, fd_check_types=True)
    assert node.node1.name == "n1"
    assert node.node1.value == "v1"
    assert node.node2 == None
    assert node.node3 == None

    data = {"node1": {"name": "n1", "value": "v1"}}
    with pytest.raises(TypeError) as e:
        node = from_dict(NodeWithOptional, data, fd_check_types=True)
    assert "missing 1 required positional argument: 'node2'" in str(e.value)
Ejemplo n.º 21
0
def test_invalid_type_discovered_in_subdict(structures: Structures):
    with pytest.raises(FromDictTypeError) as e:
        from_dict(structures.outer_structure, {"foo": 22, "baz": {"foo": 42, "bar": ["wrong type"]}},
                  fd_check_types=True, fd_global_ns=GLOBALS)

    assert str(e.value) == "For \"baz.bar\", expected <class 'str'> but found <class 'list'>"
Ejemplo n.º 22
0
def test_keyword_style_overwrites_positional(structures: Structures):
    assert from_dict(structures.inner_structure, {"foo": 42, "bar": "Works :)"}, foo=0, fd_global_ns=GLOBALS).foo == 0
Ejemplo n.º 23
0
def test_missing_key(structures: Structures):
    with pytest.raises(TypeError):
        from_dict(structures.inner_structure, {"foo": 22})
Ejemplo n.º 24
0
def test_invalid_type_from_dict(structures: Structures):
    with pytest.raises(FromDictTypeError) as e:
        from_dict(structures.inner_structure, {"foo": "wrong", "bar": "right"}, fd_check_types=True)

    assert str(e.value) == "For \"foo\", expected <class 'int'> but found <class 'str'>"
Ejemplo n.º 25
0
def test_keyword_style(structures: Structures):
    m = from_dict(structures.outer_structure, foo=22, baz=structures.inner_structure(foo=42, bar="Works :)"), fd_global_ns=GLOBALS)
    assert m.foo == 22
    assert m.baz.foo == 42
    assert m.baz.bar == "Works :)"