orionis 0.205.0__py3-none-any.whl → 0.207.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
orionis/framework.py CHANGED
@@ -5,7 +5,7 @@
5
5
  NAME = "orionis"
6
6
 
7
7
  # Current version of the framework
8
- VERSION = "0.205.0"
8
+ VERSION = "0.207.0"
9
9
 
10
10
  # Full name of the author or maintainer of the project
11
11
  AUTHOR = "Raul Mauricio Uñate Castro"
@@ -1,7 +1,8 @@
1
- from typing import Any, Type, Dict, List, Tuple, Callable, Optional, TypeVar, Set
2
- import inspect
3
1
  import abc
4
- from functools import wraps
2
+ import ast
3
+ import inspect
4
+ import types
5
+ from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Type, TypeVar
5
6
 
6
7
  ABC = TypeVar('ABC', bound=abc.ABC)
7
8
 
@@ -51,7 +52,10 @@ class ReflexionAbstract:
51
52
  Set[str]
52
53
  Set of abstract method names
53
54
  """
54
- return {name for name, _ in self._abstract.__abstractmethods__}
55
+ methods = []
56
+ for method in self._abstract.__abstractmethods__:
57
+ methods.append(method)
58
+ return set(methods)
55
59
 
56
60
  def getConcreteMethods(self) -> Dict[str, Callable]:
57
61
  """Get all concrete methods implemented in the abstract class.
@@ -88,13 +92,32 @@ class ReflexionAbstract:
88
92
  Returns
89
93
  -------
90
94
  List[str]
91
- List of class method names
95
+ List of class method names, excluding private/protected methods (starting with '_')
96
+
97
+ Notes
98
+ -----
99
+ - Uses inspect.getattr_static to avoid method binding
100
+ - Properly handles both @classmethod decorator and classmethod instances
101
+ - Filters out private/protected methods (starting with '_')
102
+
103
+ Examples
104
+ --------
105
+ >>> class MyAbstract(ABC):
106
+ ... @classmethod
107
+ ... def factory(cls): pass
108
+ ... @classmethod
109
+ ... def _protected_factory(cls): pass
110
+ >>> reflex = ReflexionAbstract(MyAbstract)
111
+ >>> reflex.getClassMethods()
112
+ ['factory']
92
113
  """
93
114
  return [
94
- name for name, member in inspect.getmembers(
95
- self._abstract,
96
- predicate=lambda x: isinstance(x, classmethod))
97
- if not name.startswith('_')
115
+ name for name in dir(self._abstract)
116
+ if not name.startswith('_') and
117
+ isinstance(
118
+ inspect.getattr_static(self._abstract, name),
119
+ (classmethod, types.MethodType)
120
+ )
98
121
  ]
99
122
 
100
123
  def getProperties(self) -> List[str]:
@@ -153,7 +176,7 @@ class ReflexionAbstract:
153
176
  """
154
177
  return tuple(
155
178
  base for base in self._abstract.__bases__
156
- if inspect.isabstract(base)
179
+ if inspect.isabstract(base) or issubclass(base, abc.ABC) or isinstance(base, abc.ABCMeta)
157
180
  )
158
181
 
159
182
  def getInterfaceMethods(self) -> Dict[str, inspect.Signature]:
@@ -220,29 +243,48 @@ class ReflexionAbstract:
220
243
  """
221
244
  return self._abstract.__annotations__
222
245
 
223
- def getDecorators(self, method_name: str) -> List[Callable]:
224
- """Get decorators applied to a method.
246
+ def getDecorators(self, method_name: str) -> List[str]:
247
+ """
248
+ Get decorators applied to a method.
225
249
 
226
250
  Parameters
227
251
  ----------
228
252
  method_name : str
229
- Name of the method
230
-
231
- Returns
232
- -------
233
- List[Callable]
234
- List of decorator functions
253
+ Name of the method to inspect
235
254
  """
236
- method = getattr(self._abstract, method_name)
237
- decorators = []
238
-
239
- if hasattr(method, '__wrapped__'):
240
- # Unwrap decorated functions
241
- while hasattr(method, '__wrapped__'):
242
- decorators.append(method)
243
- method = method.__wrapped__
255
+ method = getattr(self._abstract, method_name, None)
256
+ if method is None:
257
+ return []
244
258
 
245
- return decorators
259
+ try:
260
+ source = inspect.getsource(self._abstract)
261
+ except (OSError, TypeError):
262
+ return []
263
+
264
+ tree = ast.parse(source)
265
+
266
+ class DecoratorVisitor(ast.NodeVisitor):
267
+ def __init__(self):
268
+ self.decorators = []
269
+
270
+ def visit_FunctionDef(self, node):
271
+ if node.name == method_name:
272
+ for deco in node.decorator_list:
273
+ if isinstance(deco, ast.Name):
274
+ self.decorators.append(deco.id)
275
+ elif isinstance(deco, ast.Call):
276
+ # handles decorators with arguments like @deco(arg)
277
+ if isinstance(deco.func, ast.Name):
278
+ self.decorators.append(deco.func.id)
279
+ elif isinstance(deco, ast.Attribute):
280
+ self.decorators.append(deco.attr)
281
+ # No need to visit deeper
282
+ return
283
+
284
+ visitor = DecoratorVisitor()
285
+ visitor.visit(tree)
286
+
287
+ return visitor.decorators
246
288
 
247
289
  def isProtocol(self) -> bool:
248
290
  """Check if the abstract class is a Protocol.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: orionis
3
- Version: 0.205.0
3
+ Version: 0.207.0
4
4
  Summary: Orionis Framework – Elegant, Fast, and Powerful.
5
5
  Home-page: https://github.com/orionis-framework/framework
6
6
  Author: Raul Mauricio Uñate Castro
@@ -1,6 +1,6 @@
1
1
  orionis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  orionis/console.py,sha256=4gYWxf0fWYgJ4RKwARvnTPh06FL3GJ6SAZ7R2NzOICw,1342
3
- orionis/framework.py,sha256=fUxv8sJtO5v-ERZPJzgKhGDePNz3AbKp-n-HE7IIhZo,1469
3
+ orionis/framework.py,sha256=eb4WxXbyAXkX44A065Y_hEHg-PyA8LWfMluqcfrxYJA,1469
4
4
  orionis/installer/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
5
  orionis/installer/manager.py,sha256=Li4TVziRXWfum02xNG4JHwbnLk-u8xzHjdqKz-D894k,2755
6
6
  orionis/installer/output.py,sha256=7O9qa2xtXMB_4ZvVi-Klneom9YazwygAd_4uYAoxhbU,8548
@@ -171,7 +171,7 @@ orionis/luminate/support/inspection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQ
171
171
  orionis/luminate/support/inspection/container_integrity.py,sha256=6d9FsGk-Rm1AXgqBS3Nww49dR7n1ptXTTNyGUuBHgNY,10111
172
172
  orionis/luminate/support/inspection/functions.py,sha256=XVDLdygONcfDNlH7CZ6muNdtYHLgNp5RybqC3smL4Y4,6400
173
173
  orionis/luminate/support/inspection/reflection.py,sha256=x_UHBY9pBSKgct13-u1WbhoONqLoGG60OpgoCsKE0AI,20368
174
- orionis/luminate/support/inspection/reflexion_abstract.py,sha256=yZTl_oZACjlXKKPmQimGsfre3qQUO2hbNDf7PJ4gKZE,7661
174
+ orionis/luminate/support/inspection/reflexion_abstract.py,sha256=pKjLZFAfCHcve39FiIeAyAJiSxKhOWBkMsPub3Sa-RI,9313
175
175
  orionis/luminate/support/inspection/reflexion_concrete.py,sha256=0WOlLeTWLwMeAUReoaJetqlnT1_TxW_jMnbk_yXRR0g,549
176
176
  orionis/luminate/support/inspection/reflexion_concrete_with_abstract.py,sha256=ZuAFoSPkgbOFMIbVR0hvlkKsm1dIpY1_bsXxZxvXcmU,801
177
177
  orionis/luminate/support/inspection/reflexion_instance.py,sha256=k6bpRYjLeTUDqquluYrDZUtBLpLuGe4wm7PMUM8Sz-E,9914
@@ -199,12 +199,14 @@ tests/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
199
199
  tests/example/test_example.py,sha256=MNYissCEa0mzx1YA2gTiqXRX8r2v_vfB_Ew0jBFmBag,556
200
200
  tests/support/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
201
201
  tests/support/inspection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
202
- tests/support/inspection/test_reflection_instance.py,sha256=aYi4qmuAzQ4-gAUrtc9Lx6gNR4Mw4GcOF_T8iWsWZoQ,7266
202
+ tests/support/inspection/test_reflection_abstract.py,sha256=ntrwbhYdZBWWCuHI0k_Vttd4jclhZ-wLwopb1XhAB_k,8750
203
+ tests/support/inspection/test_reflection_instance.py,sha256=4aBFeLgOmNvO5rbyd6EFioU4_DgXddV5pL3el23mFtA,6681
203
204
  tests/support/inspection/fakes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
204
- tests/support/inspection/fakes/fake_reflection.py,sha256=G16rZdJWC3L8SGEQkmwktvw4n7IAusIIx9Tm-ZFLcg4,1419
205
- orionis-0.205.0.dist-info/LICENCE,sha256=-_4cF2EBKuYVS_SQpy1uapq0oJPUU1vl_RUWSy2jJTo,1111
206
- orionis-0.205.0.dist-info/METADATA,sha256=aFCgP3-K5OmZ5KziS4bEwafD_YPA4RxPvIZHjYCIHb0,3003
207
- orionis-0.205.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
208
- orionis-0.205.0.dist-info/entry_points.txt,sha256=a_e0faeSqyUCVZd0MqljQ2oaHHdlsz6g9sU_bMqi5zQ,49
209
- orionis-0.205.0.dist-info/top_level.txt,sha256=2bdoHgyGZhOtLAXS6Om8OCTmL24dUMC_L1quMe_ETbk,14
210
- orionis-0.205.0.dist-info/RECORD,,
205
+ tests/support/inspection/fakes/fake_reflection_abstract.py,sha256=7qtz44brfFzE4oNYi9kIsvdWP79nP2FnzSz-0bU__pg,5045
206
+ tests/support/inspection/fakes/fake_reflection_instance.py,sha256=G16rZdJWC3L8SGEQkmwktvw4n7IAusIIx9Tm-ZFLcg4,1419
207
+ orionis-0.207.0.dist-info/LICENCE,sha256=-_4cF2EBKuYVS_SQpy1uapq0oJPUU1vl_RUWSy2jJTo,1111
208
+ orionis-0.207.0.dist-info/METADATA,sha256=OTZC93qgIgplcgvUxPIBdQtjs_420Y0HUyWXCy4mshU,3003
209
+ orionis-0.207.0.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
210
+ orionis-0.207.0.dist-info/entry_points.txt,sha256=a_e0faeSqyUCVZd0MqljQ2oaHHdlsz6g9sU_bMqi5zQ,49
211
+ orionis-0.207.0.dist-info/top_level.txt,sha256=2bdoHgyGZhOtLAXS6Om8OCTmL24dUMC_L1quMe_ETbk,14
212
+ orionis-0.207.0.dist-info/RECORD,,
@@ -0,0 +1,218 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Callable
3
+ from functools import wraps
4
+
5
+ def decorator_example(func: Callable) -> Callable:
6
+ """Example decorator for testing purposes.
7
+
8
+ Parameters
9
+ ----------
10
+ func : Callable
11
+ The function to be decorated
12
+
13
+ Returns
14
+ -------
15
+ Callable
16
+ The wrapped function
17
+
18
+ Notes
19
+ -----
20
+ This is a simple identity decorator used for testing decorator detection.
21
+ """
22
+ @wraps(func)
23
+ def wrapper(*args, **kwargs):
24
+ return func(*args, **kwargs)
25
+ return wrapper
26
+
27
+
28
+ def another_decorator(func: Callable) -> Callable:
29
+ """Another example decorator for testing multiple decorators.
30
+
31
+ Parameters
32
+ ----------
33
+ func : Callable
34
+ The function to be decorated
35
+
36
+ Returns
37
+ -------
38
+ Callable
39
+ The wrapped function with added prefix
40
+
41
+ Examples
42
+ --------
43
+ >>> @another_decorator
44
+ ... def test(): return "hello"
45
+ >>> test()
46
+ 'Decorated: hello'
47
+ """
48
+ @wraps(func)
49
+ def wrapper(*args, **kwargs):
50
+ return f"Decorated: {func(*args, **kwargs)}"
51
+ return wrapper
52
+
53
+
54
+ class FakeAbstractClass(ABC):
55
+ """A fake abstract class for testing reflection capabilities.
56
+
57
+ This class contains all elements needed to test ReflexionAbstract functionality:
58
+ - Abstract methods
59
+ - Concrete methods
60
+ - Static methods
61
+ - Class methods
62
+ - Properties
63
+ - Decorated methods
64
+ - Type annotations
65
+ - Protected/private methods
66
+
67
+ Attributes
68
+ ----------
69
+ class_attr : str
70
+ A class-level attribute with type annotation
71
+ _value : float
72
+ Protected attribute used by computed_property setter
73
+ """
74
+
75
+ class_attr: str = "class_value"
76
+
77
+ @abstractmethod
78
+ def abstract_method(self, x: int, y: int) -> int:
79
+ """Required abstract method.
80
+
81
+ Parameters
82
+ ----------
83
+ x : int
84
+ First integer parameter
85
+ y : int
86
+ Second integer parameter
87
+
88
+ Returns
89
+ -------
90
+ int
91
+ The result of some operation
92
+
93
+ Notes
94
+ -----
95
+ This method must be implemented by concrete subclasses.
96
+ """
97
+ pass
98
+
99
+ @abstractmethod
100
+ def another_abstract(self, text: str) -> str:
101
+ """Another required abstract method.
102
+
103
+ Parameters
104
+ ----------
105
+ text : str
106
+ Input string to process
107
+
108
+ Returns
109
+ -------
110
+ str
111
+ Processed string result
112
+ """
113
+ pass
114
+
115
+ def concrete_method(self, value: float) -> str:
116
+ """Concrete implemented method.
117
+
118
+ Parameters
119
+ ----------
120
+ value : float
121
+ Numeric value to format
122
+
123
+ Returns
124
+ -------
125
+ str
126
+ Formatted string representation
127
+ """
128
+ return f"Value: {value}"
129
+
130
+ @staticmethod
131
+ def static_helper(flag: bool) -> str:
132
+ """Static helper method.
133
+
134
+ Parameters
135
+ ----------
136
+ flag : bool
137
+ Boolean flag to determine output
138
+
139
+ Returns
140
+ -------
141
+ str
142
+ "Enabled" if flag is True, "Disabled" otherwise
143
+ """
144
+ return "Enabled" if flag else "Disabled"
145
+
146
+ @classmethod
147
+ def create_instance(cls) -> 'FakeAbstractClass':
148
+ """Class method factory.
149
+
150
+ Returns
151
+ -------
152
+ FakeAbstractClass
153
+ New instance of the class
154
+
155
+ Notes
156
+ -----
157
+ This cannot actually instantiate the abstract class, but serves
158
+ as an example of a class method.
159
+ """
160
+ return cls()
161
+
162
+ @property
163
+ def computed_property(self) -> float:
164
+ """Computed property example.
165
+
166
+ Returns
167
+ -------
168
+ float
169
+ The value of pi approximation
170
+ """
171
+ return 3.1416
172
+
173
+ @computed_property.setter
174
+ def computed_property(self, value: float):
175
+ """Setter for computed property.
176
+
177
+ Parameters
178
+ ----------
179
+ value : float
180
+ New value to set
181
+ """
182
+ self._value = value
183
+
184
+ @decorator_example
185
+ @another_decorator
186
+ def decorated_method(self) -> str:
187
+ """Method with multiple decorators.
188
+
189
+ Returns
190
+ -------
191
+ str
192
+ Always returns "decorated" with decorator transformations
193
+
194
+ Notes
195
+ -----
196
+ Used to test decorator inspection functionality.
197
+ """
198
+ return "decorated"
199
+
200
+ def _protected_method(self) -> str:
201
+ """Protected method (should be filtered in results).
202
+
203
+ Returns
204
+ -------
205
+ str
206
+ Constant string "protected"
207
+ """
208
+ return "protected"
209
+
210
+ def __private_method(self) -> str:
211
+ """Private method (should be filtered in results).
212
+
213
+ Returns
214
+ -------
215
+ str
216
+ Constant string "private"
217
+ """
218
+ return "private"
@@ -0,0 +1,229 @@
1
+ from abc import ABC
2
+ import unittest
3
+ from orionis.luminate.support.inspection.reflection import Reflection
4
+ from orionis.luminate.test.test_output import PrinterInTest
5
+ from tests.support.inspection.fakes.fake_reflection_abstract import FakeAbstractClass
6
+
7
+ class TestReflexionAbstract(unittest.TestCase, PrinterInTest):
8
+ """Test cases for ReflexionAbstract using FakeAbstractClass.
9
+
10
+ This test suite verifies all functionality of the ReflexionAbstract class
11
+ using FakeAbstractClass as the test subject.
12
+ """
13
+
14
+ def testReflectionAbstractExceptionValueError(self):
15
+ """Class setup method.
16
+
17
+ Initializes the ReflexionAbstract instance with FakeAbstractClass
18
+ before any tests run.
19
+ """
20
+ with self.assertRaises(ValueError):
21
+ Reflection.abstract(str)
22
+
23
+ def testReflectionAbstractGetClassName(self):
24
+ """Test getClassName() method.
25
+
26
+ Verifies that:
27
+ - The returned class name matches exactly
28
+ - The return type is str
29
+ """
30
+ class_name = Reflection.abstract(FakeAbstractClass).getClassName()
31
+ self.assertEqual(class_name, "FakeAbstractClass")
32
+ self.assertIsInstance(class_name, str)
33
+
34
+ def testReflectionAbstractGetModuleName(self):
35
+ """Test getModuleName() method.
36
+
37
+ Verifies that:
38
+ - The module name is returned
39
+ - The name is a string
40
+ """
41
+ module_name = Reflection.abstract(FakeAbstractClass).getModuleName()
42
+ self.assertTrue(module_name == 'tests.support.inspection.fakes.fake_reflection_abstract')
43
+ self.assertIsInstance(module_name, str)
44
+
45
+ def testReflectionAbstractGetAbstractMethods(self):
46
+ """Test getAbstractMethods() method.
47
+
48
+ Verifies that:
49
+ - All abstract methods are detected
50
+ - No concrete methods are included
51
+ - Return type is correct
52
+ """
53
+ methods = Reflection.abstract(FakeAbstractClass).getAbstractMethods()
54
+ expected = {'abstract_method', 'another_abstract'}
55
+ self.assertEqual(methods, expected)
56
+ self.assertIsInstance(methods, set)
57
+
58
+ def testReflectionAbstractGetConcreteMethods(self):
59
+ """Test getConcreteMethods() method.
60
+
61
+ Verifies that:
62
+ - Concrete methods are detected
63
+ - Abstract methods are excluded
64
+ - Protected/private methods are excluded
65
+ """
66
+ methods = Reflection.abstract(FakeAbstractClass).getConcreteMethods()
67
+ self.assertIn('static_helper', methods)
68
+ self.assertIn('concrete_method', methods)
69
+ self.assertIn('decorated_method', methods)
70
+ self.assertNotIn('abstract_method', methods)
71
+ self.assertNotIn('_protected_method', methods)
72
+ self.assertNotIn('__private_method', methods)
73
+
74
+ def testReflectionAbstractGetStaticMethods(self):
75
+ """Test getStaticMethods() method.
76
+
77
+ Verifies that:
78
+ - Static methods are detected
79
+ - Only static methods are included
80
+ - Protected/private methods are excluded
81
+ """
82
+ static_methods = Reflection.abstract(FakeAbstractClass).getStaticMethods()
83
+ self.assertIn('static_helper', static_methods)
84
+ self.assertEqual(len(static_methods), 1)
85
+ self.assertNotIn('create_instance', static_methods)
86
+
87
+ def testReflectionAbstractGetClassMethods(self):
88
+ """Test getClassMethods() method.
89
+
90
+ Verifies that:
91
+ - Class methods are detected
92
+ - Only class methods are included
93
+ - Protected/private methods are excluded
94
+ """
95
+ class_methods = Reflection.abstract(FakeAbstractClass).getClassMethods()
96
+ self.assertIn('create_instance', class_methods)
97
+ self.assertEqual(len(class_methods), 1)
98
+ self.assertNotIn('static_helper', class_methods)
99
+
100
+ def testReflectionAbstractGetProperties(self):
101
+ """Test getProperties() method.
102
+
103
+ Verifies that:
104
+ - Properties are detected
105
+ - Only properties are included
106
+ - Protected/private properties are excluded
107
+ """
108
+ props = Reflection.abstract(FakeAbstractClass).getProperties()
109
+ self.assertIn('computed_property', props)
110
+ self.assertEqual(len(props), 1)
111
+
112
+ def testReflectionAbstractGetMethodSignature(self):
113
+ """Test getMethodSignature() method.
114
+
115
+ Verifies that:
116
+ - Correct signature is returned
117
+ - Parameters are properly detected
118
+ - Return type is properly detected
119
+ """
120
+ sig = Reflection.abstract(FakeAbstractClass).getMethodSignature('abstract_method')
121
+ params = list(sig.parameters.keys())
122
+ self.assertEqual(params, ['self', 'x', 'y'])
123
+ self.assertEqual(sig.return_annotation, int)
124
+
125
+ def testReflectionAbstractGetDocstring(self):
126
+ """Test getDocstring() method.
127
+
128
+ Verifies that:
129
+ - Docstring is returned
130
+ - Docstring contains expected content
131
+ """
132
+ doc = Reflection.abstract(FakeAbstractClass).getDocstring()
133
+ self.assertTrue(doc.startswith("A fake abstract class"))
134
+ self.assertIsInstance(doc, str)
135
+
136
+ def testReflectionAbstractGetBaseAbstractClasses(self):
137
+ """Test getBaseAbstractClasses() method.
138
+
139
+ Verifies that:
140
+ - Base abstract classes are detected
141
+ - Only abstract bases are included
142
+ """
143
+ bases = Reflection.abstract(FakeAbstractClass).getBaseAbstractClasses()
144
+ self.assertEqual(bases, (ABC,))
145
+
146
+ def testReflectionAbstractGetInterfaceMethods(self):
147
+ """Test getInterfaceMethods() method.
148
+
149
+ Verifies that:
150
+ - Interface methods are detected
151
+ - Signatures are correct
152
+ - Only abstract methods are included
153
+ """
154
+ interface = Reflection.abstract(FakeAbstractClass).getInterfaceMethods()
155
+ self.assertEqual(len(interface), 2)
156
+ self.assertIn('abstract_method', interface)
157
+ sig = interface['abstract_method']
158
+ self.assertEqual(list(sig.parameters.keys()), ['self', 'x', 'y'])
159
+
160
+ def testReflectionAbstractIsSubclassOf(self):
161
+ """Test isSubclassOf() method.
162
+
163
+ Verifies that:
164
+ - Correctly identifies abstract base classes
165
+ - Returns False for non-parent classes
166
+ """
167
+ self.assertTrue(Reflection.abstract(FakeAbstractClass).isSubclassOf(ABC))
168
+ self.assertTrue(Reflection.abstract(FakeAbstractClass).isSubclassOf(object))
169
+
170
+ def testReflectionAbstractGetSourceCode(self):
171
+ """Test getSourceCode() method.
172
+
173
+ Verifies that:
174
+ - Source code is returned
175
+ - Contains class definition
176
+ """
177
+ source = Reflection.abstract(FakeAbstractClass).getSourceCode()
178
+ self.assertIsNotNone(source)
179
+ self.assertIn("class FakeAbstractClass(ABC):", source)
180
+
181
+ def testReflectionAbstractGetFileLocation(self):
182
+ """Test getFileLocation() method.
183
+
184
+ Verifies that:
185
+ - File location is returned
186
+ - Path ends with .py extension
187
+ """
188
+ location = Reflection.abstract(FakeAbstractClass).getFileLocation()
189
+ self.assertIsNotNone(location)
190
+ self.assertTrue('fake_reflection_abstract.py' in location)
191
+
192
+ def testReflectionAbstractGetAnnotations(self):
193
+ """Test getAnnotations() method.
194
+
195
+ Verifies that:
196
+ - Annotations are detected
197
+ - Class attributes are included
198
+ """
199
+ annotations = Reflection.abstract(FakeAbstractClass).getAnnotations()
200
+ self.assertIn('class_attr', annotations)
201
+ self.assertEqual(annotations['class_attr'], str)
202
+
203
+ def testReflectionAbstractGetDecorators(self):
204
+ """Test getDecorators() method.
205
+
206
+ Verifies that:
207
+ - Decorators are detected
208
+ - Correct number of decorators is returned
209
+ - Decorator order is preserved
210
+ """
211
+ decorators = Reflection.abstract(FakeAbstractClass).getDecorators('decorated_method')
212
+ for decorator in decorators:
213
+ self.assertTrue(decorator in ['decorator_example', 'another_decorator'])
214
+
215
+ def testReflectionAbstractIsProtocol(self):
216
+ """Test isProtocol() method.
217
+
218
+ Verifies that:
219
+ - Correctly identifies non-Protocol classes
220
+ """
221
+ self.assertFalse(Reflection.abstract(FakeAbstractClass).isProtocol())
222
+
223
+ def testReflectionAbstractGetRequiredAttributes(self):
224
+ """Test getRequiredAttributes() method.
225
+
226
+ Verifies that:
227
+ - Returns empty set for non-Protocol classes
228
+ """
229
+ self.assertEqual(Reflection.abstract(FakeAbstractClass).getRequiredAttributes(), set())
@@ -2,40 +2,39 @@ import unittest
2
2
  from orionis.luminate.support.inspection.reflection import Reflection
3
3
  from orionis.luminate.support.inspection.reflexion_instance import ReflexionInstance
4
4
  from orionis.luminate.test.test_output import PrinterInTest
5
- from tests.support.inspection.fakes.fake_reflection import BaseFakeClass, FakeClass
5
+ from tests.support.inspection.fakes.fake_reflection_instance import BaseFakeClass, FakeClass
6
6
 
7
7
  class TestReflection(unittest.TestCase, PrinterInTest):
8
8
  """
9
9
  Unit tests for the Reflection class.
10
- This class tests the functionality of the Reflection class, ensuring that it correctly handles
11
10
  """
12
11
 
13
12
  def testReflectionInstanceExceptionValueError(self):
14
- """Test that Reflection.instance raises ValueError for invalid types."""
13
+ """Ensure Reflection.instance raises ValueError for invalid types."""
15
14
  with self.assertRaises(ValueError):
16
15
  Reflection.instance(str)
17
16
 
18
17
  def testReflectionInstance(self):
19
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
18
+ """Verify Reflection.instance returns an instance of ReflexionInstance."""
20
19
  self.assertIsInstance(Reflection.instance(FakeClass()), ReflexionInstance)
21
20
 
22
21
  def testReflectionInstanceGetClassName(self):
23
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
22
+ """Check that getClassName returns the correct class name."""
24
23
  reflex = Reflection.instance(FakeClass())
25
24
  self.assertEqual(reflex.getClassName(), "FakeClass")
26
25
 
27
26
  def testReflectionInstanceGetClass(self):
28
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
27
+ """Ensure getClass returns the correct class."""
29
28
  reflex = Reflection.instance(FakeClass())
30
29
  self.assertEqual(reflex.getClass(), FakeClass)
31
30
 
32
31
  def testReflectionInstanceGetModuleName(self):
33
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
32
+ """Verify getModuleName returns the correct module name."""
34
33
  reflex = Reflection.instance(FakeClass())
35
- self.assertEqual(reflex.getModuleName(), "tests.support.inspection.fakes.fake_reflection")
34
+ self.assertEqual(reflex.getModuleName(), "tests.support.inspection.fakes.fake_reflection_instance")
36
35
 
37
36
  def testReflectionInstanceGetAttributes(self):
38
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
37
+ """Check that getAttributes returns all attributes of the class."""
39
38
  reflex = Reflection.instance(FakeClass())
40
39
  attributes = reflex.getAttributes()
41
40
  self.assertTrue("public_attr" in attributes)
@@ -43,85 +42,85 @@ class TestReflection(unittest.TestCase, PrinterInTest):
43
42
  self.assertTrue("dynamic_attr" in attributes)
44
43
 
45
44
  def testReflectionInstanceGetMethods(self):
46
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
45
+ """Ensure getMethods returns all methods of the class."""
47
46
  reflex = Reflection.instance(FakeClass())
48
47
  methods = reflex.getMethods()
49
48
  self.assertTrue("instance_method" in methods)
50
49
  self.assertTrue("class_method" in methods)
51
50
 
52
51
  def testReflectionInstanceGetStaticMethods(self):
53
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
52
+ """Verify getStaticMethods returns all static methods of the class."""
54
53
  reflex = Reflection.instance(FakeClass())
55
54
  methods = reflex.getStaticMethods()
56
55
  self.assertTrue("static_method" in methods)
57
56
 
58
57
  def testReflectionInstanceGetPropertyNames(self):
59
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
58
+ """Check that getPropertyNames returns all property names."""
60
59
  reflex = Reflection.instance(FakeClass())
61
60
  properties = reflex.getPropertyNames()
62
61
  self.assertTrue("computed_property" in properties)
63
62
 
64
63
  def testReflectionInstanceCallMethod(self):
65
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
64
+ """Ensure callMethod correctly invokes a method with arguments."""
66
65
  reflex = Reflection.instance(FakeClass())
67
66
  result = reflex.callMethod("instance_method", 1, 2)
68
67
  self.assertEqual(result, 3)
69
68
 
70
69
  def testReflectionInstanceGetMethodSignature(self):
71
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
70
+ """Verify getMethodSignature returns the correct method signature."""
72
71
  reflex = Reflection.instance(FakeClass())
73
72
  signature = reflex.getMethodSignature("instance_method")
74
73
  self.assertEqual(str(signature), "(x: int, y: int) -> int")
75
74
 
76
75
  def testReflectionInstanceGetDocstring(self):
77
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
76
+ """Check that getDocstring returns the correct class docstring."""
78
77
  reflex = Reflection.instance(FakeClass())
79
78
  docstring = reflex.getDocstring()
80
79
  self.assertIn("This is a test class for ReflexionInstance", docstring)
81
80
 
82
81
  def testReflectionInstanceGetBaseClasses(self):
83
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
82
+ """Ensure getBaseClasses returns the correct base classes."""
84
83
  reflex = Reflection.instance(FakeClass())
85
84
  base_classes = reflex.getBaseClasses()
86
85
  self.assertIn(BaseFakeClass, base_classes)
87
86
 
88
87
  def testReflectionInstanceIsInstanceOf(self):
89
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
88
+ """Verify isInstanceOf checks inheritance correctly."""
90
89
  reflex = Reflection.instance(FakeClass())
91
90
  self.assertTrue(reflex.isInstanceOf(BaseFakeClass))
92
91
 
93
92
  def testReflectionInstanceGetSourceCode(self):
94
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
93
+ """Check that getSourceCode returns the class source code."""
95
94
  reflex = Reflection.instance(FakeClass())
96
95
  source_code = reflex.getSourceCode()
97
96
  self.assertIn("class FakeClass(BaseFakeClass):", source_code)
98
97
 
99
98
  def testReflectionInstanceGetFileLocation(self):
100
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
99
+ """Ensure getFileLocation returns the correct file path."""
101
100
  reflex = Reflection.instance(FakeClass())
102
101
  file_location = reflex.getFileLocation()
103
- self.assertIn("fake_reflection.py", file_location)
102
+ self.assertIn("fake_reflection_instance.py", file_location)
104
103
 
105
104
  def testReflectionInstanceGetAnnotations(self):
106
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
105
+ """Verify getAnnotations returns the correct class annotations."""
107
106
  reflex = Reflection.instance(FakeClass())
108
107
  annotations = reflex.getAnnotations()
109
108
  self.assertEqual("{'class_attr': <class 'str'>}", str(annotations))
110
109
 
111
110
  def testReflectionInstanceHasAttribute(self):
112
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
111
+ """Check that hasAttribute correctly identifies attributes."""
113
112
  reflex = Reflection.instance(FakeClass())
114
113
  self.assertTrue(reflex.hasAttribute("public_attr"))
115
114
  self.assertFalse(reflex.hasAttribute("non_existent_attr"))
116
115
 
117
116
  def testReflectionInstanceGetAttribute(self):
118
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
117
+ """Ensure getAttribute retrieves the correct attribute value."""
119
118
  reflex = Reflection.instance(FakeClass())
120
119
  attr_value = reflex.getAttribute("public_attr")
121
120
  self.assertEqual(attr_value, 42)
122
121
 
123
122
  def testReflectionInstanceGetCallableMembers(self):
124
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
123
+ """Verify getCallableMembers returns all callable members."""
125
124
  reflex = Reflection.instance(FakeClass())
126
125
  callable_members = reflex.getCallableMembers()
127
126
  self.assertIn("instance_method", callable_members)
@@ -129,19 +128,14 @@ class TestReflection(unittest.TestCase, PrinterInTest):
129
128
  self.assertIn("static_method", callable_members)
130
129
 
131
130
  def testReflectionInstanceSetAttribute(self):
132
- """Test that Reflection.instance returns an instance of ReflexionInstance."""
133
-
134
- # Create a new macro function
135
- def myMacro(cls:FakeClass, num):
131
+ """Check that setAttribute correctly sets a new attribute."""
132
+ def myMacro(cls: FakeClass, num):
136
133
  return cls.instance_method(10, 12) + num
137
134
 
138
- # Create an instance of FakeClass and set the macro as an attribute
139
135
  reflex = Reflection.instance(FakeClass())
140
136
  reflex.setAttribute("myMacro", myMacro)
141
137
 
142
- # Check if the macro was set correctly
143
138
  self.assertTrue(reflex.hasAttribute("myMacro"))
144
139
 
145
- # Call the macro method and check the result
146
140
  result = reflex.callMethod("myMacro", reflex._instance, 3)
147
- self.assertEqual(result, 25)
141
+ self.assertEqual(result, 25)