def test_timestamp_load_validation(): serializer = UtcTimestampSerializer(describe(Timestamp), None) ctx = Loading(validating=True) with pytest.raises(ValidationError): serializer.load('123421', ctx) assert serializer.load(123421, ctx) == Timestamp(123421.0) assert serializer.load(123421.0, ctx) == Timestamp(123421)
def test_decimal_load_validation(): serializer = DecimalSerializer(describe(Decimal), None) ctx = Loading(validating=True) with pytest.raises(ValidationError): serializer.load(10, ctx) with pytest.raises(ValidationError): serializer.load(9.8, ctx) with pytest.raises(ValidationError): serializer.load('', ctx) assert serializer.load('9.8', ctx) == Decimal('9.8')
def test_tuple_load_validation(): serializer = TupleSerializer(describe(Tuple[Any, Any, Any]), MockModel()) ctx = Loading(validating=True) with pytest.raises(ValidationError): serializer.load([1, 2], ctx) with pytest.raises(ValidationError): serializer.load([1, 2, 3, 4], ctx) with pytest.raises(ValidationError): serializer.load('one two three', ctx) assert serializer.load([1, 2, 3], ctx) == (1, 2, 3)
def test_str_load_validation(): serializer = StringSerializer(describe(str), None) ctx = Loading(validating=True) with pytest.raises(ValidationError): serializer.load(1, ctx) with pytest.raises(ValidationError): serializer.load(1.01, ctx) with pytest.raises(ValidationError): serializer.load(True, ctx) assert serializer.load('Something', ctx) == 'Something'
def test_int_load_validation(): serializer = IntegerSerializer(describe(int), None) ctx = Loading(validating=True) with pytest.raises(ValidationError): serializer.load(True, ctx) with pytest.raises(ValidationError): serializer.load(1.01, ctx) with pytest.raises(ValidationError): serializer.load('Something', ctx) assert serializer.load(1, ctx) == 1
def test_bool_load_validation(): serializer = BooleanSerializer(describe(bool), None) ctx = Loading(validating=True) with pytest.raises(ValidationError): serializer.load(1, ctx) with pytest.raises(ValidationError): serializer.load(1.01, ctx) with pytest.raises(ValidationError): serializer.load('Something', ctx) assert serializer.load(True, ctx) is True assert serializer.load(False, ctx) is False
def test_float_load_validation(): serializer = FloatSerializer(describe(float), None) ctx = Loading(validating=True) with pytest.raises(ValidationError): serializer.load(True, ctx) with pytest.raises(ValidationError): serializer.load('Something', ctx) loaded_int = serializer.load(1, ctx) assert loaded_int == 1 assert type(loaded_int) is float assert serializer.load(1.01, ctx) == 1.01
def test_time_load_validation(): serializer = TimeIsoSerializer(describe(time), None) ctx = Loading(validating=True) with pytest.raises(ValidationError): serializer.load(123, ctx) with pytest.raises(ValidationError): serializer.load('24:00:00', ctx) with pytest.raises(ValidationError): serializer.load('25:00:00', ctx) with pytest.raises(ValidationError): serializer.load('1:1:2', ctx) assert serializer.load('04:20:00', ctx) == time(4, 20, 00)
def test_date_load_validation(): serializer = DateIsoSerializer(describe(date), None) ctx = Loading(validating=True) with pytest.raises(ValidationError): serializer.load(123, ctx) with pytest.raises(ValidationError): serializer.load('2018-14-17', ctx) with pytest.raises(ValidationError): serializer.load('2018-11-7', ctx) with pytest.raises(ValidationError): serializer.load('2018-00-7', ctx) assert serializer.load('2018-11-17', ctx) == date(2018, 11, 17)
def test_date_time_load_validation(): serializer = DateTimeIsoSerializer(describe(datetime), None) ctx = Loading(validating=True) with pytest.raises(ValidationError): serializer.load(123421, ctx) with pytest.raises(ValidationError): serializer.load('2018-11-17T16:55:28.456753+00:0', ctx) with pytest.raises(ValidationError): serializer.load('2018-11-7T16:55:28.456753+00:00', ctx) with pytest.raises(ValidationError): serializer.load('2018-00-7T16:55:28.456753+00:00', ctx) expected = datetime(2018, 11, 17, 16, 55, 28, 456753, tzinfo=timezone.utc) assert serializer.load('2018-11-17T16:55:28.456753+00:00', ctx) == expected
def test_uuid_load_validation(): serializer = UuidSerializer(describe(UUID), None) ctx = Loading(validating=True) with pytest.raises(ValidationError): serializer.load(123421, ctx) with pytest.raises(ValidationError): serializer.load('kaalksdjfglkjsadlfjlksdjdjka', ctx) with pytest.raises(ValidationError): serializer.load('d1d61dd7-c036-47d3-a6ed-91cc2e885f-c8', ctx) with pytest.raises(ValidationError): serializer.load('d1d61dd7-c036-57d3-a6ed-91cc2e885fc8', ctx) uuid_s = 'd1d61dd7-c036-47d3-a6ed-91cc2e885fc8' assert serializer.load(uuid_s, ctx) == UUID(uuid_s) assert serializer.load(uuid_s.upper(), ctx) == UUID(uuid_s)
def __init__( self, cls: Type[T], serializers: Iterable[Type[FieldSerializer]] = field_serializers(), *, allow_any: bool = False, allow_missing: bool = False, allow_unexpected: bool = False, validate_on_load: bool = True, validate_on_dump: bool = False, ensure_frozen: Union[bool, Iterable[Type]] = False, camel_case: bool = True, indent: Optional[int] = None, ): """Initialize a JSON model. :param cls: the dataclass type to load/dump. :param serializers: field serializer classes in an order they will be tested for fitness for each field. :param allow_any: `False` to raise if the model contains fields annotated with `Any` (this includes generics like `List[Any]`, or simply `list`). :param allow_missing: `False` to raise during load if data is missing the optional fields. :param allow_unexpected: `False` to raise during load if data contains some unknown fields. :param validate_on_load: to call dataclass `__validate__` method after object construction. :param validate_on_load: to call object `__validate__` before dumping. :param ensure_frozen: `False` to skip check of model immutability; `True` will perform the check against built-in immutable types; a list of custom immutable types is added to built-ins. :param camel_case: `True` to transform dataclass "snake_case" to JSON "camelCase". :param indent: number of spaces JSON output will be indented by; `None` for most compact representation. """ self.cls = cls self.descriptor = describe(cls) self.serious_model: SeriousModel = SeriousModel( self.descriptor, serializers, allow_any=allow_any, allow_missing=allow_missing, allow_unexpected=allow_unexpected, validate_on_load=validate_on_load, validate_on_dump=validate_on_dump, ensure_frozen=ensure_frozen, key_mapper=JsonKeyMapper() if camel_case else None, ) self._dump_indentation = indent
def __init__( self, cls: Type[T], serializers: Iterable[Type[FieldSerializer]] = field_serializers(), *, allow_any: bool = False, allow_missing: bool = False, allow_unexpected: bool = False, validate_on_load: bool = True, validate_on_dump: bool = False, ensure_frozen: Union[bool, Iterable[Type]] = False, ): """Initialize a dictionary model. :param cls: the dataclass type to load/dump. :param serializers: field serializer classes in an order they will be tested for fitness for each field. :param allow_any: `False` to raise if the model contains fields annotated with `Any` (this includes generics like `List[Any]`, or simply `list`). :param allow_missing: `False` to raise during load if data is missing the optional fields. :param allow_unexpected: `False` to raise during load if data contains some unknown fields. :param validate_on_load: to call dataclass `__validate__` method after object construction. :param validate_on_dump: to call object `__validate__` before dumping. :param ensure_frozen: `False` to skip check of model immutability; `True` will perform the check against built-in immutable types; a list of custom immutable types is added to built-ins. """ self.cls = cls self.descriptor = describe(cls) self.serious_model = SeriousModel( self.descriptor, serializers, allow_any=allow_any, allow_missing=allow_missing, allow_unexpected=allow_unexpected, validate_on_load=validate_on_load, validate_on_dump=validate_on_dump, ensure_frozen=ensure_frozen, )
def test_str(self): serializer = EnumSerializer(describe(Color), None) ctx = Loading(validating=True) with pytest.raises(ValidationError): serializer.load('#f00', ctx) assert serializer.load('#ff0000', ctx) is Color.RED
def test_number(self): serializer = EnumSerializer(describe(Constant), None) ctx = Loading(validating=True) with pytest.raises(ValidationError): serializer.load(9.18, ctx) assert serializer.load(3.14, ctx) is Constant.PI
def test_dict_load_validation(): serializer = DictSerializer(describe(Dict[str, Any]), MockModel()) ctx = Loading(validating=True) with pytest.raises(ValidationError): serializer.load('string', ctx) assert serializer.load({'one': 'two'}, ctx) == {'one': 'two'}
def test_frozen_list_load_validation(): serializer = CollectionSerializer(describe(FrozenList[Any]), MockModel()) ctx = Loading(validating=True) with pytest.raises(ValidationError): serializer.load('string', ctx) assert serializer.load([1, 2, 3], ctx) == FrozenList([1, 2, 3])