Coverage for tests/unit/json_serialize/serializable_dataclass/test_sdc_properties_nested.py: 98%

45 statements  

« prev     ^ index     » next       coverage.py v7.6.1, created at 2025-04-04 03:33 -0600

1from __future__ import annotations 

2 

3import sys 

4 

5import pytest 

6 

7from muutils.json_serialize import SerializableDataclass, serializable_dataclass 

8from muutils.json_serialize.util import _FORMAT_KEY 

9 

10SUPPORTS_KW_ONLY: bool = sys.version_info >= (3, 10) 

11 

12print(f"{SUPPORTS_KW_ONLY = }") 

13 

14 

15@serializable_dataclass 

16class Person(SerializableDataclass): 

17 first_name: str 

18 last_name: str 

19 

20 @property 

21 def full_name(self) -> str: 

22 return f"{self.first_name} {self.last_name}" 

23 

24 

25# TODO: idk why it thinks `SUPPORTS_KW_ONLY` is not a True or False Literal: 

26# error: "kw_only" argument must be a True or False literal [literal-required] 

27@serializable_dataclass( 

28 kw_only=SUPPORTS_KW_ONLY, # type: ignore[literal-required] 

29 properties_to_serialize=["full_name", "full_title"], 

30) 

31class TitledPerson(Person): 

32 title: str 

33 

34 @property 

35 def full_title(self) -> str: 

36 return f"{self.title} {self.full_name}" 

37 

38 

39@serializable_dataclass( 

40 kw_only=SUPPORTS_KW_ONLY, # type: ignore[literal-required] 

41 properties_to_serialize=["full_name", "not_a_real_property"], 

42) 

43class AgedPerson_not_valid(Person): 

44 title: str 

45 

46 @property 

47 def full_title(self) -> str: 

48 return f"{self.title} {self.full_name}" 

49 

50 

51def test_invalid_properties_to_serialize(): 

52 instance = AgedPerson_not_valid(first_name="Jane", last_name="Smith", title="Dr.") 

53 

54 with pytest.raises(AttributeError): 

55 instance.serialize() 

56 

57 

58def test_serialize_person(): 

59 instance = Person(first_name="John", last_name="Doe") 

60 

61 serialized = instance.serialize() 

62 

63 assert serialized == { 

64 "first_name": "John", 

65 "last_name": "Doe", 

66 _FORMAT_KEY: "Person(SerializableDataclass)", 

67 } 

68 

69 recovered = Person.load(serialized) 

70 

71 assert recovered == instance 

72 

73 

74def test_serialize_titled_person(): 

75 instance = TitledPerson(first_name="Jane", last_name="Smith", title="Dr.") 

76 

77 if SUPPORTS_KW_ONLY: 

78 with pytest.raises(TypeError): 

79 TitledPerson("Jane", "Smith", "Dr.") 

80 

81 serialized = instance.serialize() 

82 

83 assert serialized == { 

84 "first_name": "Jane", 

85 "last_name": "Smith", 

86 "title": "Dr.", 

87 _FORMAT_KEY: "TitledPerson(SerializableDataclass)", 

88 "full_name": "Jane Smith", 

89 "full_title": "Dr. Jane Smith", 

90 } 

91 

92 recovered = TitledPerson.load(serialized) 

93 

94 assert recovered == instance