def test_parses_dataclass(self) -> None: pavlova = Pavlova() parsed = pavlova.from_mapping({ 'enabled': False, 'date': '2018-01-01', 'portion': 0.1, 'count': 10, 'name': 'Bob', 'price': '10.01', 'data': {'extra': 'args'}, 'color': 'red', 'locations': ['Sydney', 'Melbourne'], 'country': 'Australia', }, Sample) self.assertTrue(isinstance(parsed, Sample)) self.assertEqual(parsed.enabled, False) self.assertEqual(parsed.date, datetime(year=2018, month=1, day=1)) self.assertTrue(0.09 < parsed.portion < 0.11) self.assertEqual(parsed.count, 10) self.assertEqual(parsed.name, 'Bob') self.assertEqual(parsed.price, Decimal('10.01')) self.assertEqual(parsed.data, {'extra': 'args'}) self.assertEqual(parsed.color, SampleEnum.RED) self.assertEqual(parsed.locations, ['Sydney', 'Melbourne']) self.assertEqual(parsed.country, 'Australia') self.assertTrue(parsed.nested is None)
def test_missing_value_causes_error(self) -> None: pavlova = Pavlova() with self.assertRaises(PavlovaParsingError) as raised: pavlova.from_mapping({}, SimpleSample) exc = raised.exception self.assertTrue(isinstance(exc.original_exception, TypeError)) self.assertEqual(exc.path, ('value',))
def test_missing_nested_parsing(self) -> None: @dataclass class Nested: nested: Optional[NestedSample] = None pavlova = Pavlova() parsed = pavlova.from_mapping({'nested': None}, Nested) self.assertTrue(isinstance(parsed, Nested)) self.assertIsNone(parsed.nested)
def test_nested_parsing(self) -> None: @dataclass class Nested: nested: NestedSample pavlova = Pavlova() parsed = pavlova.from_mapping({'nested': {'key': 'locked'}}, Nested) self.assertTrue(isinstance(parsed, Nested)) self.assertTrue(isinstance(parsed.nested, NestedSample)) self.assertEqual(parsed.nested.key, 'locked')
def test_with_generic_parser(self) -> None: @dataclass class Example: email: Email pavlova = Pavlova() pavlova.register_parser(Email, GenericParser(pavlova, Email)) pavlova.from_mapping({'email': '*****@*****.**'}, Example) with self.assertRaises(PavlovaParsingError): pavlova.from_mapping({'email': 'chris'}, Example) with self.assertRaises(PavlovaParsingError): pavlova.from_mapping({'email': 123}, Example)
def test_returns_correct_values(self) -> None: parser: PavlovaParser = pavlova.parsers.UnionParser(Pavlova()) self.assertEqual( parser.parse_input('yes', Optional[bool], tuple()), True, )
def test_parses_enum_value(self) -> None: parser: PavlovaParser = pavlova.parsers.EnumParser(Pavlova()) self.assertEqual(parser.parse_input(1, SampleEnum, tuple()), SampleEnum.RED) self.assertEqual(parser.parse_input(2, SampleEnum, tuple()), SampleEnum.GREEN)
def test_raises_typeerror_for_unions(self) -> None: parser: PavlovaParser = pavlova.parsers.UnionParser(Pavlova()) with self.assertRaises(TypeError): parser.parse_input('', Union[str], tuple()) with self.assertRaises(TypeError): parser.parse_input('', Union[str, int], tuple())
def test_parses_int(self) -> None: parser: PavlovaParser = pavlova.parsers.IntParser(Pavlova()) self.assertEqual(parser.parse_input('10', int, tuple()), 10) self.assertEqual(parser.parse_input(10, int, tuple()), 10) self.assertEqual(parser.parse_input(10.1, int, tuple()), 10) self.assertEqual(parser.parse_input(-10.1, int, tuple()), -10) self.assertEqual(parser.parse_input('-10', int, tuple()), -10)
def test_parses_string(self) -> None: parser: PavlovaParser = pavlova.parsers.EnumParser(Pavlova()) self.assertEqual(parser.parse_input('red', SampleEnum, tuple()), SampleEnum.RED) self.assertEqual(parser.parse_input('RED', SampleEnum, tuple()), SampleEnum.RED) self.assertEqual(parser.parse_input('gReEn', SampleEnum, tuple()), SampleEnum.GREEN)
def test_calls_generic_type(self) -> None: parser = pavlova.parsers.GenericParser(Pavlova(), Email) self.assertEqual( parser.parse_input('chris@chris', Email, tuple()), 'chris@chris', ) with self.assertRaises(ValueError): parser.parse_input('chris', Email, tuple())
def test_parses_datetime(self) -> None: parser: PavlovaParser = pavlova.parsers.DatetimeParser(Pavlova()) value = parser.parse_input('2018-01-02T03:10:11+03:00', datetime, tuple()) self.assertEqual(value.year, 2018) self.assertEqual(value.month, 1) self.assertEqual(value.day, 2) self.assertEqual(value.hour, 3) self.assertEqual(value.minute, 10) self.assertEqual(value.second, 11) self.assertEqual(value.strftime('%z'), '+0300')
def test_parses_int(self) -> None: parser: PavlovaParser = pavlova.parsers.DecimalParser(Pavlova()) self.assertEqual(parser.parse_input('10', Decimal, tuple()), Decimal('10')) self.assertEqual(parser.parse_input(10, Decimal, tuple()), Decimal('10.0')) self.assertTrue( Decimal('10') < parser.parse_input(10.1, Decimal, tuple()) < Decimal('10.2')) self.assertEqual(parser.parse_input('-10', Decimal, tuple()), Decimal('-10')) self.assertEqual(parser.parse_input('-10.1', Decimal, tuple()), Decimal('-10.1'))
def test_non_string_truthy_values(self) -> None: parser: PavlovaParser = pavlova.parsers.BoolParser(Pavlova()) input_values = (1, True, 1.0) self.assertTrue( all(parser.parse_input(v, bool, tuple()) for v in input_values))
def test_returns_correct_dictionary(self) -> None: parser: PavlovaParser = pavlova.parsers.DictParser(Pavlova()) value = parser.parse_input({1: 'yes'}, Dict[str, bool], tuple()) self.assertEqual(value, {'1': True})
def test_raises_typeerror_for_different_types(self) -> None: parser: PavlovaParser = pavlova.parsers.DictParser(Pavlova()) with self.assertRaises(TypeError): parser.parse_input('', Dict[str, bool], tuple())
def test_returns_string(self) -> None: parser: PavlovaParser = pavlova.parsers.StringParser(Pavlova()) value = parser.parse_input(False, str, tuple()) self.assertEqual(type(value), str) self.assertEqual(value, 'False')
def test_raises_typeerror_for_different_types(self) -> None: parser: PavlovaParser = pavlova.parsers.ListParser(Pavlova()) with self.assertRaises(TypeError): parser.parse_input([0, 1, 'a'], List[bool], tuple())
def test_returns_correct_values(self) -> None: parser: PavlovaParser = pavlova.parsers.ListParser(Pavlova()) values = parser.parse_input([0, 1, 2], List[bool], tuple()) self.assertEqual(values, [False, True, True])
def test_non_list_input_raises_typeerror(self) -> None: parser: PavlovaParser = pavlova.parsers.ListParser(Pavlova()) with self.assertRaises(TypeError): parser.parse_input('', List[int], tuple())
def test_non_string_falsy_values(self) -> None: parser: PavlovaParser = pavlova.parsers.BoolParser(Pavlova()) input_values = (0, None, False) self.assertFalse( any(parser.parse_input(v, bool, tuple()) for v in input_values))
def test_doesnt_parse_string_float(self) -> None: parser: PavlovaParser = pavlova.parsers.IntParser(Pavlova()) with self.assertRaises(Exception): self.assertEqual(parser.parse_input('10.1', int, tuple()), 10)
def test_non_boolean_string_raise_typeerror(self) -> None: parser: PavlovaParser = pavlova.parsers.BoolParser(Pavlova()) with self.assertRaises(TypeError): parser.parse_input('aaa', bool, tuple())
def test_falsy_string_values(self) -> None: parser: PavlovaParser = pavlova.parsers.BoolParser(Pavlova()) input_values = ('no', 'false', '0') self.assertFalse( any(parser.parse_input(v, bool, tuple()) for v in input_values))
def test_truthy_string_values(self) -> None: parser: PavlovaParser = pavlova.parsers.BoolParser(Pavlova()) input_values = ('yes', 'true', '1') self.assertTrue( all(parser.parse_input(v, bool, tuple()) for v in input_values))