orionis 0.301.0__py3-none-any.whl → 0.303.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.
@@ -0,0 +1,500 @@
1
+ import importlib
2
+ import inspect
3
+ import keyword
4
+ from orionis.services.introspection.exceptions.reflection_type_error import ReflectionTypeError
5
+ from orionis.services.introspection.exceptions.reflection_value_error import ReflectionValueError
6
+ from orionis.services.introspection.modules.contracts.reflection_instance import IReflectionModule
7
+
8
+ class ReflectionModule(IReflectionModule):
9
+
10
+ def __init__(self, module: str):
11
+ """
12
+ Parameters
13
+ ----------
14
+ module : str
15
+ The name of the module to import and reflect upon.
16
+ Raises
17
+ ------
18
+ ReflectionTypeError
19
+ If `module` is not a non-empty string or if the module cannot be imported.
20
+ Notes
21
+ -----
22
+ This constructor attempts to import the specified module using `importlib.import_module`.
23
+ If the import fails or the module name is invalid, a `ReflectionTypeError` is raised.
24
+ """
25
+ if not isinstance(module, str) or not module.strip():
26
+ raise ReflectionTypeError(f"Module name must be a non-empty string, got {repr(module)}")
27
+ try:
28
+ self.__module = importlib.import_module(module)
29
+ except Exception as e:
30
+ raise ReflectionTypeError(f"Failed to import module '{module}': {e}") from e
31
+
32
+ def getModule(self):
33
+ """
34
+ Returns the module object.
35
+
36
+ Returns
37
+ -------
38
+ module
39
+ The imported module object.
40
+ """
41
+ return self.__module
42
+
43
+ def hasClass(self, class_name: str) -> bool:
44
+ """
45
+ Check if the module contains a class with the specified name.
46
+
47
+ Parameters
48
+ ----------
49
+ class_name : str
50
+ The name of the class to check for.
51
+
52
+ Returns
53
+ -------
54
+ bool
55
+ True if the class exists in the module, False otherwise.
56
+ """
57
+ return class_name in self.getClasses()
58
+
59
+ def getClass(self, class_name: str):
60
+ """
61
+ Get a class by its name from the module.
62
+
63
+ Parameters
64
+ ----------
65
+ class_name : str
66
+ The name of the class to retrieve.
67
+
68
+ Returns
69
+ -------
70
+ type
71
+ The class object if found, None otherwise.
72
+ """
73
+ classes = self.getClasses()
74
+ if class_name in classes:
75
+ return classes[class_name]
76
+
77
+ return None
78
+
79
+ def setClass(self, class_name: str, cls: type) -> bool:
80
+ """
81
+ Set a class in the module.
82
+
83
+ Parameters
84
+ ----------
85
+ class_name : str
86
+ The name of the class to set.
87
+ cls : type
88
+ The class object to set.
89
+
90
+ Raises
91
+ ------
92
+ ValueError
93
+ If `cls` is not a class or if `class_name` is not a valid identifier.
94
+ """
95
+ if not isinstance(cls, type):
96
+ raise ReflectionValueError(f"Expected a class type, got {type(cls)}")
97
+ if not class_name.isidentifier():
98
+ raise ReflectionValueError(f"Invalid class name '{class_name}'. Must be a valid identifier.")
99
+ if keyword.iskeyword(class_name):
100
+ raise ReflectionValueError(f"Class name '{class_name}' is a reserved keyword.")
101
+
102
+ setattr(self.__module, class_name, cls)
103
+ return True
104
+
105
+ def removeClass(self, class_name: str) -> bool:
106
+ """
107
+ Remove a class from the module.
108
+
109
+ Parameters
110
+ ----------
111
+ class_name : str
112
+ The name of the class to remove.
113
+
114
+ Raises
115
+ ------
116
+ ValueError
117
+ If `class_name` is not a valid identifier or if the class does not exist.
118
+ """
119
+ if class_name not in self.getClasses():
120
+ raise ValueError(f"Class '{class_name}' does not exist in module '{self.__module.__name__}'")
121
+
122
+ delattr(self.__module, class_name)
123
+ return True
124
+
125
+ def initClass(self, class_name: str, *args, **kwargs):
126
+ """
127
+ Initialize a class from the module with the given arguments.
128
+
129
+ Parameters
130
+ ----------
131
+ class_name : str
132
+ The name of the class to initialize.
133
+ *args
134
+ Positional arguments to pass to the class constructor.
135
+ **kwargs
136
+ Keyword arguments to pass to the class constructor.
137
+
138
+ Returns
139
+ -------
140
+ object
141
+ An instance of the class initialized with the provided arguments.
142
+
143
+ Raises
144
+ ------
145
+ ReflectionValueError
146
+ If the class does not exist or if the class name is not a valid identifier.
147
+ """
148
+
149
+ cls = self.getClass(class_name)
150
+ if cls is None:
151
+ raise ReflectionValueError(f"Class '{class_name}' does not exist in module '{self.__module.__name__}'")
152
+
153
+ return cls(*args, **kwargs)
154
+
155
+ def getClasses(self) -> dict:
156
+ """
157
+ Returns a dictionary of classes defined in the module.
158
+
159
+ Returns
160
+ -------
161
+ dict
162
+ A dictionary where keys are class names and values are class objects.
163
+ """
164
+ classes = {}
165
+
166
+ # Check if it's a module
167
+ for k, v in self.__module.__dict__.items():
168
+ if isinstance(v, type) and issubclass(v, object):
169
+ classes[k] = v
170
+
171
+ # Return the dictionary of classes
172
+ return classes
173
+
174
+ def getPublicClasses(self) -> dict:
175
+ """
176
+ Returns a dictionary of public classes defined in the module.
177
+
178
+ Returns
179
+ -------
180
+ dict
181
+ A dictionary where keys are class names and values are class objects.
182
+ """
183
+ public_classes = {}
184
+ for k, v in self.getClasses().items():
185
+ if not str(k).startswith('_'):
186
+ public_classes[k] = v
187
+ return public_classes
188
+
189
+ def getProtectedClasses(self) -> dict:
190
+ """
191
+ Returns a dictionary of protected classes defined in the module.
192
+
193
+ Returns
194
+ -------
195
+ dict
196
+ A dictionary where keys are class names and values are class objects.
197
+ """
198
+ protected_classes = {}
199
+ for k, v in self.getClasses().items():
200
+ if str(k).startswith('_') and not str(k).startswith('__'):
201
+ protected_classes[k] = v
202
+
203
+ return protected_classes
204
+
205
+ def getPrivateClasses(self) -> dict:
206
+ """
207
+ Returns a dictionary of private classes defined in the module.
208
+
209
+ Returns
210
+ -------
211
+ dict
212
+ A dictionary where keys are class names and values are class objects.
213
+ """
214
+ private_classes = {}
215
+ for k, v in self.getClasses().items():
216
+ if str(k).startswith('__') and not str(k).endswith('__'):
217
+ private_classes[k] = v
218
+
219
+ return private_classes
220
+
221
+ def getConstant(self, constant_name: str):
222
+ """
223
+ Get a constant by its name from the module.
224
+
225
+ Parameters
226
+ ----------
227
+ constant_name : str
228
+ The name of the constant to retrieve.
229
+
230
+ Returns
231
+ -------
232
+ Any
233
+ The value of the constant if found, None otherwise.
234
+ """
235
+ constants = self.getConstants()
236
+ if constant_name in constants:
237
+ return constants[constant_name]
238
+
239
+ return None
240
+
241
+ def getConstants(self) -> dict:
242
+ """
243
+ Returns a dictionary of constants defined in the module.
244
+
245
+ Returns
246
+ -------
247
+ dict
248
+ A dictionary where keys are constant names and values are their values.
249
+ """
250
+ constants = {}
251
+ for k, v in self.__module.__dict__.items():
252
+ if not callable(v) and k.isupper() and not keyword.iskeyword(k):
253
+ constants[k] = v
254
+
255
+ return constants
256
+
257
+ def getPublicConstants(self) -> dict:
258
+ """
259
+ Returns a dictionary of public constants defined in the module.
260
+
261
+ Returns
262
+ -------
263
+ dict
264
+ A dictionary where keys are constant names and values are their values.
265
+ """
266
+ public_constants = {}
267
+ for k, v in self.getConstants().items():
268
+ if not str(k).startswith('_'):
269
+ public_constants[k] = v
270
+
271
+ return public_constants
272
+
273
+ def getProtectedConstants(self) -> dict:
274
+ """
275
+ Returns a dictionary of protected constants defined in the module.
276
+
277
+ Returns
278
+ -------
279
+ dict
280
+ A dictionary where keys are constant names and values are their values.
281
+ """
282
+ protected_constants = {}
283
+ for k, v in self.getConstants().items():
284
+ if str(k).startswith('_') and not str(k).startswith('__'):
285
+ protected_constants[k] = v
286
+
287
+ return protected_constants
288
+
289
+ def getPrivateConstants(self) -> dict:
290
+ """
291
+ Returns a dictionary of private constants defined in the module.
292
+
293
+ Returns
294
+ -------
295
+ dict
296
+ A dictionary where keys are constant names and values are their values.
297
+ """
298
+ private_constants = {}
299
+ for k, v in self.getConstants().items():
300
+ if str(k).startswith('__') and not str(k).endswith('__'):
301
+ private_constants[k] = v
302
+
303
+ return private_constants
304
+
305
+ def getFunctions(self) -> dict:
306
+ """
307
+ Returns a dictionary of functions defined in the module.
308
+
309
+ Returns
310
+ -------
311
+ dict
312
+ A dictionary where keys are function names and values are function objects.
313
+ """
314
+ functions = {}
315
+ for k, v in self.__module.__dict__.items():
316
+ if callable(v):
317
+ if hasattr(v, '__code__'):
318
+ functions[k] = v
319
+
320
+ return functions
321
+
322
+ def getPublicFunctions(self) -> dict:
323
+ """
324
+ Returns a dictionary of public functions defined in the module.
325
+
326
+ Returns
327
+ -------
328
+ dict
329
+ A dictionary where keys are function names and values are function objects.
330
+ """
331
+ public_functions = {}
332
+ for k, v in self.getFunctions().items():
333
+ if not str(k).startswith('_'):
334
+ public_functions[k] = v
335
+
336
+ return public_functions
337
+
338
+ def getPublicSyncFunctions(self) -> dict:
339
+ """
340
+ Returns a dictionary of public synchronous functions defined in the module.
341
+
342
+ Returns
343
+ -------
344
+ dict
345
+ A dictionary where keys are function names and values are function objects.
346
+ """
347
+ sync_functions = {}
348
+ for k, v in self.getPublicFunctions().items():
349
+ if not v.__code__.co_flags & 0x80:
350
+ sync_functions[k] = v
351
+ return sync_functions
352
+
353
+ def getPublicAsyncFunctions(self) -> dict:
354
+ """
355
+ Returns a dictionary of public asynchronous functions defined in the module.
356
+
357
+ Returns
358
+ -------
359
+ dict
360
+ A dictionary where keys are function names and values are function objects.
361
+ """
362
+ async_functions = {}
363
+ for k, v in self.getPublicFunctions().items():
364
+ if v.__code__.co_flags & 0x80:
365
+ async_functions[k] = v
366
+ return async_functions
367
+
368
+ def getProtectedFunctions(self) -> dict:
369
+ """
370
+ Returns a dictionary of protected functions defined in the module.
371
+
372
+ Returns
373
+ -------
374
+ dict
375
+ A dictionary where keys are function names and values are function objects.
376
+ """
377
+ protected_functions = {}
378
+ for k, v in self.getFunctions().items():
379
+ if str(k).startswith('_') and not str(k).startswith('__'):
380
+ protected_functions[k] = v
381
+
382
+ return protected_functions
383
+
384
+ def getProtectedSyncFunctions(self) -> dict:
385
+ """
386
+ Returns a dictionary of protected synchronous functions defined in the module.
387
+
388
+ Returns
389
+ -------
390
+ dict
391
+ A dictionary where keys are function names and values are function objects.
392
+ """
393
+ sync_functions = {}
394
+ for k, v in self.getProtectedFunctions().items():
395
+ if not v.__code__.co_flags & 0x80:
396
+ sync_functions[k] = v
397
+ return sync_functions
398
+
399
+ def getProtectedAsyncFunctions(self) -> dict:
400
+ """
401
+ Returns a dictionary of protected asynchronous functions defined in the module.
402
+
403
+ Returns
404
+ -------
405
+ dict
406
+ A dictionary where keys are function names and values are function objects.
407
+ """
408
+ async_functions = {}
409
+ for k, v in self.getProtectedFunctions().items():
410
+ if v.__code__.co_flags & 0x80:
411
+ async_functions[k] = v
412
+ return async_functions
413
+
414
+ def getPrivateFunctions(self) -> dict:
415
+ """
416
+ Returns a dictionary of private functions defined in the module.
417
+
418
+ Returns
419
+ -------
420
+ dict
421
+ A dictionary where keys are function names and values are function objects.
422
+ """
423
+ private_functions = {}
424
+ for k, v in self.getFunctions().items():
425
+ if str(k).startswith('__') and not str(k).endswith('__'):
426
+ private_functions[k] = v
427
+
428
+ return private_functions
429
+
430
+ def getPrivateSyncFunctions(self) -> dict:
431
+ """
432
+ Returns a dictionary of private synchronous functions defined in the module.
433
+
434
+ Returns
435
+ -------
436
+ dict
437
+ A dictionary where keys are function names and values are function objects.
438
+ """
439
+ sync_functions = {}
440
+ for k, v in self.getPrivateFunctions().items():
441
+ if not v.__code__.co_flags & 0x80:
442
+ sync_functions[k] = v
443
+ return sync_functions
444
+
445
+ def getPrivateAsyncFunctions(self) -> dict:
446
+ """
447
+ Returns a dictionary of private asynchronous functions defined in the module.
448
+
449
+ Returns
450
+ -------
451
+ dict
452
+ A dictionary where keys are function names and values are function objects.
453
+ """
454
+ async_functions = {}
455
+ for k, v in self.getPrivateFunctions().items():
456
+ if v.__code__.co_flags & 0x80:
457
+ async_functions[k] = v
458
+ return async_functions
459
+
460
+ def getImports(self) -> dict:
461
+ """
462
+ Returns a dictionary of imported modules in the module.
463
+
464
+ Returns
465
+ -------
466
+ dict
467
+ A dictionary where keys are import names and values are module objects.
468
+ """
469
+ imports = {}
470
+ for k, v in self.__module.__dict__.items():
471
+ if isinstance(v, type(importlib)):
472
+ imports[k] = v
473
+
474
+ return imports
475
+
476
+ def getFile(self) -> str:
477
+ """
478
+ Returns the file name of the module.
479
+
480
+ Returns
481
+ -------
482
+ str
483
+ The file name of the module.
484
+ """
485
+ return inspect.getfile(self.__module)
486
+
487
+ def getSourceCode(self) -> str:
488
+ """
489
+ Returns the source code of the module.
490
+
491
+ Returns
492
+ -------
493
+ str
494
+ The source code of the module.
495
+ """
496
+ try:
497
+ with open(self.getFile(), 'r', encoding='utf-8') as file:
498
+ return file.read()
499
+ except Exception as e:
500
+ raise ReflectionValueError(f"Failed to read source code for module '{self.__module.__name__}': {e}") from e
@@ -22,16 +22,4 @@ class ITestSuite(ABC):
22
22
  OrionisTestConfigException
23
23
  If the provided configuration is not an instance of Configuration.
24
24
  """
25
- pass
26
-
27
- @abstractmethod
28
- def getResult(self) -> UnitTest:
29
- """
30
- Returns the results of the executed test suite.
31
-
32
- Returns
33
- -------
34
- UnitTest
35
- The result of the executed test suite.
36
- """
37
25
  pass
@@ -14,7 +14,8 @@ class IUnitTest(ABC):
14
14
  print_result: bool = None,
15
15
  throw_exception: bool = False,
16
16
  persistent: bool = False,
17
- persistent_driver: str = 'sqlite'
17
+ persistent_driver: str = 'sqlite',
18
+ web_report: bool = False
18
19
  ):
19
20
  """
20
21
  Configures the UnitTest instance with the specified parameters.
@@ -163,4 +164,56 @@ class IUnitTest(ABC):
163
164
 
164
165
  Resets the internal test suite to an empty `unittest.TestSuite`, removing any previously added tests.
165
166
  """
167
+ pass
168
+
169
+ @abstractmethod
170
+ def getResult(self) -> dict:
171
+ """
172
+ Returns the results of the executed test suite.
173
+
174
+ Returns
175
+ -------
176
+ UnitTest
177
+ The result of the executed test suite.
178
+ """
179
+ pass
180
+
181
+ @abstractmethod
182
+ def getOutputBuffer(self) -> int:
183
+ """
184
+ Returns the output buffer used for capturing test results.
185
+ This method returns the internal output buffer that collects the results of the test execution.
186
+ Returns
187
+ -------
188
+ int
189
+ The output buffer containing the results of the test execution.
190
+ """
191
+ pass
192
+
193
+ @abstractmethod
194
+ def printOutputBuffer(self) -> None:
195
+ """
196
+ Prints the contents of the output buffer to the console.
197
+ This method retrieves the output buffer and prints its contents using the rich console.
198
+ """
199
+ pass
200
+
201
+ @abstractmethod
202
+ def getErrorBuffer(self) -> int:
203
+ """
204
+ Returns the error buffer used for capturing test errors.
205
+ This method returns the internal error buffer that collects any errors encountered during test execution.
206
+ Returns
207
+ -------
208
+ int
209
+ The error buffer containing the errors encountered during the test execution.
210
+ """
211
+ pass
212
+
213
+ @abstractmethod
214
+ def printErrorBuffer(self) -> None:
215
+ """
216
+ Prints the contents of the error buffer to the console.
217
+ This method retrieves the error buffer and prints its contents using the rich console.
218
+ """
166
219
  pass
@@ -39,9 +39,8 @@ class TestSuite(ITestSuite):
39
39
  Configuration object specifying parameters for test suite execution. If not provided, a new Configuration instance is created.
40
40
  """
41
41
  self.__config = config or Configuration()
42
- self.__result = None
43
42
 
44
- def run(self) -> UnitTest:
43
+ def run(self) -> 'UnitTest':
45
44
  """
46
45
  Runs the test suite based on the provided configuration.
47
46
 
@@ -119,17 +118,6 @@ class TestSuite(ITestSuite):
119
118
  tags=config.tags if config.tags else None
120
119
  )
121
120
 
122
- # Return the initialized test suite
123
- self.__result = tests.run()
124
- return self
125
-
126
- def getResult(self) -> UnitTest:
127
- """
128
- Returns the results of the executed test suite.
129
-
130
- Returns
131
- -------
132
- UnitTest
133
- The result of the executed test suite.
134
- """
135
- return self.__result
121
+ # Run the test suite and return the UnitTest instance
122
+ tests.run()
123
+ return tests