1414from random import Random
1515from unittest import TestCase
1616
17+ # ## Python Third Party Imports ----
18+ from pytest import raises
19+
1720# ## Local First Party Imports ----
18- from toolbox_python .classes import get_full_class_name
21+ from toolbox_python .classes import ( # cached_class_property,
22+ class_property ,
23+ get_full_class_name ,
24+ )
1925from toolbox_python .defaults import Defaults
2026
2127
2228# ---------------------------------------------------------------------------- #
2329# #
24- # Test Suite ####
30+ # get_full_class_name() ####
2531# #
2632# ---------------------------------------------------------------------------- #
2733
@@ -48,3 +54,138 @@ def test_get_full_class_name_3(self) -> None:
4854 _output : str = get_full_class_name (_input )
4955 _expected = "random.Random"
5056 assert _output == _expected
57+
58+
59+ # ---------------------------------------------------------------------------- #
60+ # #
61+ # class_property() ####
62+ # #
63+ # ---------------------------------------------------------------------------- #
64+
65+
66+ class MyClass :
67+ _class_value : str = "original"
68+
69+ def __init__ (self , instance_value : str = "instance" ) -> None :
70+ self ._instance_value : str = instance_value
71+
72+ @class_property
73+ def class_value (cls ) -> str :
74+ return cls ._class_value
75+
76+ # @class_value.getter
77+ # def class_value_getter(cls) -> str:
78+ # return cls._class_value
79+
80+ @class_property
81+ def class_value_modified (cls ) -> str :
82+ return cls ._class_value + " modified"
83+
84+ @class_property ()
85+ def class_value_with_parens (cls ) -> str :
86+ return cls ._class_value + " with parens"
87+
88+ @class_property (doc = "This is a class property with a docstring." )
89+ def class_value_with_doc (cls ) -> str :
90+ """This is a class property with a docstring."""
91+ return cls ._class_value + " with doc"
92+
93+ @class_property
94+ @classmethod
95+ def class_value_method (cls ) -> str :
96+ """This is a class method."""
97+ return cls ._class_value + " with method"
98+
99+ @property
100+ def instance_value (self ) -> str :
101+ return self ._instance_value
102+
103+
104+ class TestClassProperty (TestCase ):
105+
106+ def setUp (self ) -> None :
107+ MyClass ._class_value = "original"
108+
109+ def test_class_property_class_property (self ) -> None :
110+ assert MyClass .class_value == "original"
111+
112+ def test_class_property_class_property_modified (self ) -> None :
113+ MyClass ._class_value = "modified"
114+ assert MyClass .class_value == "modified"
115+
116+ def test_class_property_instance_property (self ) -> None :
117+ assert MyClass ().instance_value == "instance"
118+
119+ def test_class_property_properties (self ) -> None :
120+ new_class = MyClass ()
121+ assert new_class .class_value == "original"
122+ assert new_class .instance_value == "instance"
123+
124+ # def test_class_property_getter(self) -> None:
125+ # assert MyClass.class_value_getter == MyClass.class_value
126+
127+ def test_class_property_modified_properties (self ) -> None :
128+
129+ # Test the instance property for an instance of MyClass
130+ new_class = MyClass ("instance value" )
131+ assert new_class .instance_value == "instance value"
132+
133+ # Test the modified value of an instance property for the instantiated class
134+ new_class ._instance_value = "new instance value"
135+ assert new_class .instance_value == "new instance value"
136+
137+ # Test the class property for an instance of MyClass
138+ # This should return the original class value, not the modified one
139+ new_class ._class_value = "new class value"
140+ assert new_class .class_value == "original"
141+
142+ def test_class_property_with_parens (self ) -> None :
143+ assert MyClass .class_value_with_parens == "original with parens"
144+ MyClass ._class_value = "modified"
145+ assert MyClass .class_value_with_parens == "modified with parens"
146+
147+ def test_class_property_with_doc (self ) -> None :
148+ assert MyClass .class_value_with_doc == "original with doc"
149+ MyClass .class_value_with_doc .__doc__ == (
150+ "This is a class property with a docstring."
151+ )
152+
153+ def test_class_property_errors (self ) -> None :
154+ with raises (AttributeError ):
155+ MyClass ().missing_property
156+ with raises (AttributeError ):
157+ MyClass .missing_property
158+ with raises (AttributeError ):
159+ MyClass ().missing_class_property
160+ with raises (AttributeError ):
161+ MyClass .missing_class_property
162+
163+ def test_class_property_setter (self ) -> None :
164+
165+ with raises (NotImplementedError ):
166+
167+ class MyClassWithSetter :
168+ _class_value : str = "original"
169+
170+ @class_property
171+ def class_value (cls ) -> str :
172+ return cls ._class_value
173+
174+ @class_value .setter
175+ def class_value (cls , value : str ) -> None :
176+ cls ._class_value = value
177+
178+ def test_class_property_deleter (self ) -> None :
179+
180+ with raises (NotImplementedError ):
181+
182+ class MyClassWithDeleter :
183+ _class_value : str = "original"
184+
185+ @class_property
186+ def class_value (cls ) -> str :
187+ return cls ._class_value
188+
189+ @class_value .deleter
190+ def class_value (cls ) -> None :
191+ del cls ._class_value
0 commit comments