Beispiel #1
0
    def test_should_raise_error_if_key_not_found(self):
        @dataclass
        class TestClass:
            my_field: str = field_from_dict()

        @dataclass
        class TestClassWithDictKeySpecified:
            my_field: str = field_from_dict("myFieldInDict")

        # Check the message with no dict_key specified
        with self.assertRaises(DictKeyNotFoundError) as context:
            dataclass_from_dict(TestClass, {"unexpectedField": "value"})

        expected_message = "Could not find a dictionary key for the my_field field."
        self.assertEqual(expected_message, str(context.exception))

        # Check the message with dict_key specified
        with self.assertRaises(DictKeyNotFoundError) as with_dict_key_context:
            dataclass_from_dict(TestClassWithDictKeySpecified,
                                {"unexpectedField": "value"})

        with_dict_key_expected_message = (
            "Could not find a dictionary key for the my_field field (with 'myFieldInDict' specified as dict_key)."
        )
        self.assertEqual(with_dict_key_expected_message,
                         str(with_dict_key_context.exception))
Beispiel #2
0
    def test_should_raise_error_if_attribute_cannot_be_converted(self):
        @dataclass
        class TestClass:
            my_field: Decimal = field_from_dict()

        origin_dict = {"myField": "cannot_convert"}

        with self.assertRaises(DictValueConversionError) as context:
            dataclass_from_dict(TestClass, origin_dict)

        expected_message = (
            "Could not convert dictionary value to type Decimal for field my_field. Found value 'cannot_convert' of "
            "type str.")
        self.assertEqual(expected_message, str(context.exception))
Beispiel #3
0
    def test_should_error_if_non_optional_field_name_exists_in_dict_but_has_none_value(
            self):
        @dataclass
        class TestClass(DataclassFromDict):
            my_field: str = field_from_dict()

        origin_dict = {"my_field": None}

        with self.assertRaises(DictValueNotFoundError) as context:
            dataclass_from_dict(TestClass, origin_dict)

        expected_message = (
            "A value of None was found for the field, my_field but the field does not have an optional type. If you "
            "expect the value of this field to potentially be None, you can make its type Optional[str]."
        )
        self.assertEqual(str(context.exception), expected_message)
Beispiel #4
0
    def test_should_get_field_of_list_of_dataclasses(self):
        @dataclass
        class TestChildClass:
            my_field: str = field_from_dict("testChildStrField")
            field_with_converter: str = field_from_dict(
                "testChildConvertedField", lambda x: "convertedValue")

        @dataclass
        class TestClass:
            children: List[TestChildClass] = field_from_dict()

        origin_dict = {
            "children": [
                {
                    "testChildStrField": "testStrValue",
                    "testChildConvertedField": "testRawValue",
                },
                {
                    "testChildStrField": "testStrValue",
                    "testChildConvertedField": "testRawValue",
                },
            ]
        }

        expected = TestClass(children=[
            TestChildClass(my_field="testStrValue",
                           field_with_converter="convertedValue"),
            TestChildClass(my_field="testStrValue",
                           field_with_converter="convertedValue"),
        ])
        self.assertEqual(expected, dataclass_from_dict(TestClass, origin_dict))
Beispiel #5
0
    def test_should_get_field_of_list_type(self):
        @dataclass
        class TestClass:
            my_field: List[str] = field_from_dict("testList")

        origin_dict = {"testList": ["value1", "value2"]}

        expected = TestClass(my_field=["value1", "value2"])
        self.assertEqual(expected, dataclass_from_dict(TestClass, origin_dict))
Beispiel #6
0
    def test_should_use_field_name_if_dict_key_is_missing(self):
        @dataclass
        class TestClass:
            my_field: str = field_from_dict()

        origin_dict = {"my_field": "valueDoesntMatter"}

        expected = TestClass(my_field="valueDoesntMatter")
        self.assertEqual(expected, dataclass_from_dict(TestClass, origin_dict))
Beispiel #7
0
    def test_should_use_field_converter_if_present(self):
        @dataclass
        class TestClass:
            my_field: str = field_from_dict(
                "testField", converter=lambda x: "converter_result")

        origin_dict = {"testField": "valueDoesntMatter"}

        expected = TestClass(my_field="converter_result")
        self.assertEqual(expected, dataclass_from_dict(TestClass, origin_dict))
Beispiel #8
0
    def test_should_use_converter_for_list_field(self):
        @dataclass
        class TestClass:
            my_field: List[str] = field_from_dict(
                converter=lambda x: ["convertedValue"])

        origin_dict = {"myField": []}

        expected = TestClass(my_field=["convertedValue"])
        self.assertEqual(expected, dataclass_from_dict(TestClass, origin_dict))
Beispiel #9
0
    def test_should_use_camel_cased_field_name_if_dict_key_is_missing_and_dict_has_camel_case_keys(
            self):
        @dataclass
        class TestClass(DataclassFromDict):
            my_field: str = field_from_dict()

        origin_dict = {"myField": "valueDoesntMatter"}

        expected = TestClass(my_field="valueDoesntMatter")
        self.assertEqual(expected, dataclass_from_dict(TestClass, origin_dict))
Beispiel #10
0
    def test_not_should_raise_error_if_key_not_found_for_field_with_default_value(
            self):
        @dataclass
        class TestClass:
            my_field: str = field_from_dict("notFoundField",
                                            default="default value")

        origin_dict = {"unexpectedField": "value"}

        expected = TestClass(my_field="default value")
        self.assertEqual(expected, dataclass_from_dict(TestClass, origin_dict))
Beispiel #11
0
    def test_should_not_error_if_optional_field_name_exists_in_dict_but_has_none_value(
            self):
        # Inspired by this happening in another project

        @dataclass
        class TestClass(DataclassFromDict):
            my_field: Optional[str] = field_from_dict()

        origin_dict = {"my_field": None}

        expected = TestClass(my_field=None)
        self.assertEqual(expected, dataclass_from_dict(TestClass, origin_dict))
Beispiel #12
0
    def test_should_raise_error_if_list_field_doesnt_specify_item_type(self):
        @dataclass
        class TestClass1:
            list_field: List = field_from_dict()

        @dataclass
        class TestClass2:
            list_field: list = field_from_dict()

        origin_dict = {"listField": []}

        with self.assertRaises(UnspecificListFieldError):
            dataclass_from_dict(TestClass1, origin_dict)

        with self.assertRaises(UnspecificListFieldError) as context:
            dataclass_from_dict(TestClass2, origin_dict)

        expected_message = (
            "An item type was not specified for the list field, list_field. Please give the field a type like "
            "'List[<item type>]' to allow conversion from a dictionary.")
        self.assertEqual(expected_message, str(context.exception))
Beispiel #13
0
    def test_should_get_field_of_dataclass_type(self):
        @dataclass
        class TestChildClass:
            my_field: str = field_from_dict()

        @dataclass
        class TestClass:
            child_field: TestChildClass = field_from_dict()

        origin_dict = {"childField": {"myField": "testChildFieldValue"}}

        expected = TestClass(child_field=TestChildClass(
            my_field="testChildFieldValue"))
        self.assertEqual(expected, dataclass_from_dict(TestClass, origin_dict))
Beispiel #14
0
    def test_should_get_non_primitive_values_if_no_conversion_is_needed(self):
        class MyCustomClass:
            pass

        @dataclass
        class TestClass:
            decimal_field: Decimal = field_from_dict()
            custom_class_field: MyCustomClass = field_from_dict()

        custom_class_instance = MyCustomClass()

        origin_dict = {
            "custom_class_field": custom_class_instance,
            "decimal_field": Decimal(1),
        }

        expected = TestClass(
            decimal_field=Decimal(1),
            custom_class_field=custom_class_instance,
        )
        self.assertEqual(expected, dataclass_from_dict(TestClass, origin_dict))
Beispiel #15
0
    def test_should_get_basic_field_values_from_dict(self):
        @dataclass
        class TestClass:
            test_bool_field: bool = field_from_dict("testBoolField")
            test_float_field: float = field_from_dict("testFloatField")
            test_int_field: int = field_from_dict("testIntField")
            test_str_field: str = field_from_dict("testStrField")

        origin_dict = {
            "testBoolField": True,
            "testFloatField": 12.34,
            "testIntField": 123,
            "testStrField": "string_value",
        }

        expected = TestClass(
            test_bool_field=True,
            test_float_field=12.34,
            test_int_field=123,
            test_str_field="string_value",
        )
        self.assertEqual(expected, dataclass_from_dict(TestClass, origin_dict))
Beispiel #16
0
    def test_should_return_dataclass_instance(self):
        @dataclass
        class TestClass:
            my_field: str = "default"

        self.assertEqual(TestClass(), dataclass_from_dict(TestClass, {}))
 def from_dict(cls, origin_dict: dict):
     """Init an instance of this dataclass from a dictionary"""
     return dict_to_dataclass.dataclass_from_dict(cls, origin_dict)