def it_handles_dataclasses(expect): converter = converters.map_type(MyDataclass) expect(converter.__name__) == "MyDataclassConverter" expect(converter.CONVERTERS) == { "foobar": converters.Integer, "flag": converters.Boolean, }
def when_list_of_dataclasses(expect): converter = converters.map_type(List[MyDataclass]) data = [{'foobar': 1}, {'foobar': 2}, {'foobar': 3}] value = [MyDataclass(1), MyDataclass(2), MyDataclass(3)] expect(converter.to_python_value(data, target=None)) == value
def it_handles_dataclasses(expect): converter = converters.map_type(MyDataclass) expect(converter.__name__) == 'MyDataclassConverter' expect(converter.CONVERTERS) == { 'foobar': converters.Integer, 'flag': converters.Boolean, }
def when_list_of_dataclasses(expect): converter = converters.map_type(List[MyDataclass]) value = [MyDataclass(1), MyDataclass(2), MyDataclass(3)] data = [ {'foobar': 1, 'flag': False}, {'foobar': 2, 'flag': False}, {'foobar': 3, 'flag': False}, ] expect(converter.to_preserialization_data(value)) == data expect(converter.to_preserialization_data(data)) == data
def it_rejects_non_types(expect): with expect.raises(TypeError, "Annotation is not a type: 'foobar'"): converters.map_type("foobar")
def it_rejects_unknown_types(expect): with expect.raises( TypeError, "Could not map type: <class 'datafiles.tests.test_converters.MyNonDataclass'>", ): converters.map_type(MyNonDataclass)
def it_handles_string_type_annotations_for_extensions(expect): converter = converters.map_type("Number") expect(converter.TYPE) == float expect(converter.__name__) == "Number"
def it_rejects_unknown_types(expect): with expect.raises(TypeError): converters.map_type(MyNonDataclass)
def it_requires_list_annotations_to_have_a_type(expect): with expect.raises(TypeError): converters.map_type(List)
def it_handles_list_annotations(expect): converter = converters.map_type(List[str]) expect(converter.__name__) == 'StringList' expect(converter.CONVERTER) == converters.String
@dataclass class MyDataclass: foobar: int flag: bool = False class MyNonDataclass: pass IntegerList = converters.List.subclass(converters.Integer) StringList = converters.List.subclass(converters.String) MyDict = converters.Dictionary.subclass(converters.String, converters.Integer) MyDataclassConverter = converters.map_type(MyDataclass) MyDataclassConverterList = converters.map_type(List[MyDataclass]) def describe_map_type(): def it_handles_extended_types(expect): converter = converters.map_type(converters.Number) expect(converter.__name__) == 'Number' def it_handles_list_annotations(expect): converter = converters.map_type(List[str]) expect(converter.__name__) == 'StringList' expect(converter.CONVERTER) == converters.String def it_handles_list_annotations_of_dataclasses(expect): converter = converters.map_type(List[MyDataclass])
def it_requires_dict_annotations_to_have_types(expect): with expect.raises(TypeError, "Types are required with 'Dict' annotation"): converters.map_type(Dict)
def it_handles_abstract_mapping_types(expect): converter = converters.map_type(Mapping[str, int]) expect(converter.__name__) == "StringIntegerDict"
def it_requires_set_annotations_to_have_a_type(expect): with expect.raises(TypeError, "Type is required with 'Set' annotation"): converters.map_type(Set)
def it_handles_set_annotations_of_dataclasses(expect): converter = converters.map_type(Set[MyDataclass]) expect(converter.__name__) == "MyDataclassConverterSet" expect(converter.CONVERTER.__name__) == "MyDataclassConverter"
def it_handles_set_annotations(expect): converter = converters.map_type(Set[str]) expect(converter.__name__) == "StringSet" expect(converter.CONVERTER) == converters.String
def when_optional_enum(expect): convert = converters.map_type(Optional[Color]).to_preserialization_data expect(convert(None)).is_(None)
def when_optional_enum(expect): convert = converters.map_type(Optional[Color]).to_python_value expect(convert(None)).is_(None)
def it_rejects_unhandled_type_annotations(expect): with expect.raises( TypeError, "Unsupported container type: <class 'collections.abc.ByteString'>", ): converters.map_type(ByteString)
def when_enum(expect): convert = converters.map_type(Color).to_python_value expect(convert(1)).is_(Color.RED) with expect.raises(ValueError): convert(42)
def it_handles_extended_types(expect): converter = converters.map_type(converters.Number) expect(converter.__name__) == 'Number'
def when_enum(expect): convert = converters.map_type(Color).to_preserialization_data expect(convert(Color.RED)) == 1
def it_handles_list_annotations_of_dataclasses(expect): converter = converters.map_type(List[MyDataclass]) expect(converter.__name__) == 'MyDataclassConverterList' expect(converter.CONVERTER.__name__) == 'MyDataclassConverter'
def with_new_type(expect): converters.register(MyCustomString, converters.String) converter = converters.map_type(MyCustomString) expect(converter) == converters.String
def it_handles_dict_annotations(expect): converter = converters.map_type(Dict[str, int]) expect(converter.__name__) == 'StringIntegerDict'
def it_handles_enums(expect): converter = converters.map_type(Color) expect(converter.__name__) == 'ColorConverter'
def it_handles_optionals(expect): converter = converters.map_type(Optional[str]) expect(converter.__name__) == 'OptionalString' expect(converter.TYPE) == str expect(converter.DEFAULT) == None
def it_handles_string_type_annotations(expect): converter = converters.map_type('float') expect(converter.TYPE) == float
def it_rejects_unhandled_type_annotations(expect): with expect.raises(TypeError): converters.map_type(ByteString)
def it_handles_optionals_with_legacy_syntax(expect): converter = converters.map_type(Optional[str]) expect(converter.__name__) == "OptionalString" expect(converter.TYPE) == str expect(converter.DEFAULT).is_(None)