orionis 0.245.0__py3-none-any.whl → 0.247.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 +1 -1
- orionis/luminate/config/app/__init__.py +10 -0
- orionis/luminate/config/app/entities/app.py +205 -0
- orionis/luminate/config/app/enums/ciphers.py +34 -0
- orionis/luminate/config/app/enums/environments.py +15 -0
- orionis/luminate/config/auth/__init__.py +7 -0
- orionis/luminate/config/auth/entities/auth.py +11 -0
- orionis/luminate/config/cache/__init__.py +9 -0
- orionis/luminate/config/cache/entities/cache.py +58 -0
- orionis/luminate/config/cache/entities/file.py +29 -0
- orionis/luminate/config/cache/entities/stores.py +35 -0
- orionis/luminate/config/cache/enums/drivers.py +12 -0
- orionis/luminate/config/contracts/config.py +27 -0
- orionis/luminate/config/entities/testing.py +215 -0
- orionis/luminate/config/exceptions/integrity_exception.py +30 -0
- orionis/luminate/console/dumper/dump_die.py +418 -0
- orionis/luminate/contracts/facades/commands/scheduler_facade.py +1 -1
- orionis/luminate/facades/files/path_facade.py +1 -1
- orionis/luminate/patterns/__init__.py +4 -0
- orionis/luminate/patterns/singleton/__init__.py +10 -0
- orionis/luminate/patterns/singleton/meta_class.py +56 -0
- orionis/luminate/providers/commands/reactor_commands_service_provider.py +3 -3
- orionis/luminate/providers/commands/scheduler_provider.py +1 -1
- orionis/luminate/providers/config/config_service_provider.py +1 -1
- orionis/luminate/providers/environment/environment__service_provider.py +2 -2
- orionis/luminate/providers/files/paths_provider.py +1 -1
- orionis/luminate/providers/log/log_service_provider.py +2 -2
- orionis/luminate/services/environment/__init__.py +10 -0
- orionis/luminate/services/environment/contracts/__init__.py +5 -0
- orionis/luminate/services/environment/contracts/env.py +93 -0
- orionis/luminate/services/environment/dot_env.py +293 -0
- orionis/luminate/services/environment/env.py +77 -0
- orionis/luminate/services/paths/__init__.py +9 -0
- orionis/luminate/services/paths/contracts/__init__.py +0 -0
- orionis/luminate/services/paths/contracts/resolver.py +67 -0
- orionis/luminate/services/paths/resolver.py +83 -0
- orionis/luminate/services/workers/__init__.py +10 -0
- orionis/luminate/services/workers/maximum_workers.py +36 -0
- orionis/luminate/services_/__init__.py +0 -0
- orionis/luminate/services_/commands/__init__.py +0 -0
- orionis/luminate/services_/config/__init__.py +0 -0
- orionis/luminate/services_/log/__init__.py +0 -0
- orionis/luminate/support/introspection/abstracts/entities/__init__.py +0 -0
- orionis/luminate/support/introspection/abstracts/entities/abstract_class_attributes.py +11 -0
- orionis/luminate/support/introspection/abstracts/reflect_abstract.py +154 -16
- orionis/luminate/support/introspection/instances/reflection_instance.py +2 -2
- orionis/luminate/test/__init__.py +11 -1
- orionis/luminate/test/cases/test_async.py +1 -10
- orionis/luminate/test/cases/test_case.py +8 -3
- orionis/luminate/test/cases/test_sync.py +1 -0
- orionis/luminate/test/core/contracts/test_suite.py +19 -31
- orionis/luminate/test/core/contracts/test_unit.py +103 -59
- orionis/luminate/test/core/test_suite.py +50 -42
- orionis/luminate/test/core/test_unit.py +756 -196
- orionis/luminate/test/entities/test_result.py +19 -18
- orionis/luminate/test/enums/test_mode.py +16 -0
- orionis/luminate/test/exceptions/test_config_exception.py +28 -0
- orionis/luminate/test/exceptions/test_exception.py +41 -34
- orionis/luminate/test/output/contracts/test_std_out.py +22 -11
- orionis/luminate/test/output/test_std_out.py +79 -48
- {orionis-0.245.0.dist-info → orionis-0.247.0.dist-info}/METADATA +4 -1
- {orionis-0.245.0.dist-info → orionis-0.247.0.dist-info}/RECORD +98 -61
- tests/config/__init__.py +0 -0
- tests/config/test_app.py +122 -0
- tests/config/test_auth.py +21 -0
- tests/config/test_cache.py +20 -0
- tests/patterns/__init__.py +0 -0
- tests/patterns/singleton/__init__.py +0 -0
- tests/patterns/singleton/test_singleton.py +18 -0
- tests/services/__init__.py +0 -0
- tests/services/environment/__init__.py +0 -0
- tests/services/environment/test_env.py +33 -0
- tests/support/inspection/fakes/fake_reflect_abstract.py +61 -5
- tests/support/inspection/test_reflect_abstract.py +62 -1
- tests/support/inspection/test_reflect_instance.py +0 -1
- orionis/luminate/config/app.py +0 -47
- orionis/luminate/config/auth.py +0 -15
- orionis/luminate/config/cache.py +0 -51
- orionis/luminate/support/environment/contracts/env.py +0 -68
- orionis/luminate/support/environment/env.py +0 -138
- orionis/luminate/support/environment/functions.py +0 -49
- orionis/luminate/support/environment/helper.py +0 -26
- orionis/luminate/support/patterns/singleton.py +0 -44
- tests/support/environment/test_env.py +0 -91
- tests/support/patterns/test_singleton.py +0 -18
- /orionis/luminate/{services/commands → config/app/entities}/__init__.py +0 -0
- /orionis/luminate/{services/config → config/app/enums}/__init__.py +0 -0
- /orionis/luminate/{services/log → config/auth/entities}/__init__.py +0 -0
- /orionis/luminate/{support/environment → config/cache/entities}/__init__.py +0 -0
- /orionis/luminate/{support/environment/contracts → config/cache/enums}/__init__.py +0 -0
- /orionis/luminate/{support/patterns → config/contracts}/__init__.py +0 -0
- /orionis/luminate/config/{cors.py → entities/cors.py} +0 -0
- /orionis/luminate/config/{database.py → entities/database.py} +0 -0
- /orionis/luminate/config/{filesystems.py → entities/filesystems.py} +0 -0
- /orionis/luminate/config/{logging.py → entities/logging.py} +0 -0
- /orionis/luminate/config/{mail.py → entities/mail.py} +0 -0
- /orionis/luminate/config/{queue.py → entities/queue.py} +0 -0
- /orionis/luminate/config/{session.py → entities/session.py} +0 -0
- {tests/support/environment → orionis/luminate/config/exceptions}/__init__.py +0 -0
- {tests/support/patterns → orionis/luminate/console/dumper}/__init__.py +0 -0
- /orionis/luminate/{services → services_}/commands/reactor_commands_service.py +0 -0
- /orionis/luminate/{services → services_}/commands/scheduler_service.py +0 -0
- /orionis/luminate/{services → services_}/config/config_service.py +0 -0
- /orionis/luminate/{services → services_}/log/log_service.py +0 -0
- {orionis-0.245.0.dist-info → orionis-0.247.0.dist-info}/LICENCE +0 -0
- {orionis-0.245.0.dist-info → orionis-0.247.0.dist-info}/WHEEL +0 -0
- {orionis-0.245.0.dist-info → orionis-0.247.0.dist-info}/entry_points.txt +0 -0
- {orionis-0.245.0.dist-info → orionis-0.247.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,67 @@
|
|
1
|
+
from abc import ABC, abstractmethod
|
2
|
+
from typing import Optional
|
3
|
+
|
4
|
+
class IResolver(ABC):
|
5
|
+
"""
|
6
|
+
Interface for a utility class that resolves file and directory paths relative to a base path.
|
7
|
+
"""
|
8
|
+
|
9
|
+
@abstractmethod
|
10
|
+
def __init__(self, root_path: Optional[str] = None):
|
11
|
+
"""
|
12
|
+
Initializes the resolver with an optional root path.
|
13
|
+
|
14
|
+
Parameters
|
15
|
+
----------
|
16
|
+
root_path : str, optional
|
17
|
+
The root directory to resolve relative paths from.
|
18
|
+
"""
|
19
|
+
pass
|
20
|
+
|
21
|
+
@abstractmethod
|
22
|
+
def relativePath(self, relative_path: str):
|
23
|
+
"""
|
24
|
+
Resolves a relative path into an absolute one and validates its existence.
|
25
|
+
|
26
|
+
Parameters
|
27
|
+
----------
|
28
|
+
relative_path : str
|
29
|
+
The relative path to resolve.
|
30
|
+
|
31
|
+
Returns
|
32
|
+
-------
|
33
|
+
ResolverInterface
|
34
|
+
The instance itself for method chaining.
|
35
|
+
|
36
|
+
Raises
|
37
|
+
------
|
38
|
+
FileNotFoundError
|
39
|
+
If the resolved path does not exist.
|
40
|
+
ValueError
|
41
|
+
If the resolved path is neither a file nor a directory.
|
42
|
+
"""
|
43
|
+
pass
|
44
|
+
|
45
|
+
@abstractmethod
|
46
|
+
def toString(self) -> str:
|
47
|
+
"""
|
48
|
+
Returns the resolved path as a string.
|
49
|
+
|
50
|
+
Returns
|
51
|
+
-------
|
52
|
+
str
|
53
|
+
The resolved path.
|
54
|
+
"""
|
55
|
+
pass
|
56
|
+
|
57
|
+
@abstractmethod
|
58
|
+
def __str__(self) -> str:
|
59
|
+
"""
|
60
|
+
Returns the resolved path as a string (for print or str()).
|
61
|
+
|
62
|
+
Returns
|
63
|
+
-------
|
64
|
+
str
|
65
|
+
The resolved path.
|
66
|
+
"""
|
67
|
+
pass
|
@@ -0,0 +1,83 @@
|
|
1
|
+
import os
|
2
|
+
from pathlib import Path
|
3
|
+
from orionis.luminate.support.paths.contracts.resolver import IResolver
|
4
|
+
|
5
|
+
class Resolver(IResolver):
|
6
|
+
"""
|
7
|
+
A utility class for resolving file and directory paths relative to the project's root directory.
|
8
|
+
"""
|
9
|
+
|
10
|
+
def __init__(self, root_path: str = None):
|
11
|
+
"""
|
12
|
+
Initializes the Resolver instance with the project's root directory.
|
13
|
+
|
14
|
+
Parameters
|
15
|
+
----------
|
16
|
+
root_path : str, optional
|
17
|
+
The root directory of the project. If not provided, it defaults to the current working directory.
|
18
|
+
"""
|
19
|
+
self.base_path = Path(root_path).resolve() if root_path else Path(os.getcwd()).resolve()
|
20
|
+
self.resolved_path = None
|
21
|
+
|
22
|
+
def relativePath(self, relative_path: str) -> 'Resolver':
|
23
|
+
"""
|
24
|
+
Resolves a given relative path to an absolute path and validates its existence.
|
25
|
+
|
26
|
+
This method combines the project's root directory with the provided relative path,
|
27
|
+
resolves it to an absolute path, and ensures it exists as either a directory or a file.
|
28
|
+
|
29
|
+
Parameters
|
30
|
+
----------
|
31
|
+
relative_path : str
|
32
|
+
The relative path to a directory or file to be resolved.
|
33
|
+
|
34
|
+
Returns
|
35
|
+
-------
|
36
|
+
Resolver
|
37
|
+
The current instance of the Resolver class with the resolved path.
|
38
|
+
|
39
|
+
Raises
|
40
|
+
------
|
41
|
+
FileNotFoundError
|
42
|
+
If the resolved path does not exist.
|
43
|
+
ValueError
|
44
|
+
If the resolved path is neither a valid directory nor a file.
|
45
|
+
"""
|
46
|
+
# Combine the base path with the relative path and resolve it
|
47
|
+
resolved_path = (self.base_path / relative_path).resolve()
|
48
|
+
|
49
|
+
# Validate that the path exists
|
50
|
+
if not resolved_path.exists():
|
51
|
+
raise FileNotFoundError(f"The requested path does not exist: {resolved_path}")
|
52
|
+
|
53
|
+
# Validate that the path is either a directory or a file
|
54
|
+
if not (resolved_path.is_dir() or resolved_path.is_file()):
|
55
|
+
raise ValueError(f"The requested path is neither a valid directory nor a file: {resolved_path}")
|
56
|
+
|
57
|
+
# Store the resolved path in the instance variable
|
58
|
+
self.resolved_path = resolved_path
|
59
|
+
|
60
|
+
# Return the current instance
|
61
|
+
return self
|
62
|
+
|
63
|
+
def toString(self) -> str:
|
64
|
+
"""
|
65
|
+
Returns the string representation of the resolved path.
|
66
|
+
|
67
|
+
Returns
|
68
|
+
-------
|
69
|
+
str
|
70
|
+
The resolved path as a string.
|
71
|
+
"""
|
72
|
+
return str(self.resolved_path)
|
73
|
+
|
74
|
+
def __str__(self) -> str:
|
75
|
+
"""
|
76
|
+
Returns the string representation of the resolved path.
|
77
|
+
|
78
|
+
Returns
|
79
|
+
-------
|
80
|
+
str
|
81
|
+
The resolved path as a string.
|
82
|
+
"""
|
83
|
+
return str(self.resolved_path)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
from orionis.luminate.services.workers.maximum_workers import MaximumWorkers
|
2
|
+
|
3
|
+
__all__ = [
|
4
|
+
"MaximumWorkers",
|
5
|
+
]
|
6
|
+
__author__ = "Raúl Mauricio Uñate Castro"
|
7
|
+
__description__ = (
|
8
|
+
"This module provides a class to calculate the maximum number of workers "
|
9
|
+
"that can be run on a machine based on its CPU and memory resources. "
|
10
|
+
)
|
@@ -0,0 +1,36 @@
|
|
1
|
+
import multiprocessing
|
2
|
+
import math
|
3
|
+
import psutil
|
4
|
+
|
5
|
+
class MaximumWorkers:
|
6
|
+
"""
|
7
|
+
Calculates the optimal number of workers a machine can handle based on CPU and memory resources.
|
8
|
+
|
9
|
+
This class estimates the maximum number of Uvicorn (or similar) workers by considering:
|
10
|
+
- The number of available CPU cores.
|
11
|
+
- The total system memory (RAM).
|
12
|
+
- The estimated memory usage per worker (configurable).
|
13
|
+
|
14
|
+
Parameters
|
15
|
+
----------
|
16
|
+
ram_per_worker : float, optional
|
17
|
+
Estimated amount of RAM (in GB) that each worker will consume. Default is 0.5 GB.
|
18
|
+
"""
|
19
|
+
|
20
|
+
def __init__(self, ram_per_worker: float = 0.5):
|
21
|
+
self._cpu_count = multiprocessing.cpu_count()
|
22
|
+
self._ram_total_gb = psutil.virtual_memory().total / (1024 ** 3)
|
23
|
+
self._ram_per_worker = ram_per_worker
|
24
|
+
|
25
|
+
def calculate(self) -> int:
|
26
|
+
"""
|
27
|
+
Computes the maximum number of workers supported by the current machine.
|
28
|
+
|
29
|
+
Returns
|
30
|
+
-------
|
31
|
+
int
|
32
|
+
The recommended number of worker processes based on CPU and memory limits.
|
33
|
+
"""
|
34
|
+
max_workers_by_cpu = self._cpu_count
|
35
|
+
max_workers_by_ram = math.floor(self._ram_total_gb / self._ram_per_worker)
|
36
|
+
return min(max_workers_by_cpu, max_workers_by_ram)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,11 @@
|
|
1
|
+
from dataclasses import dataclass
|
2
|
+
from typing import Any, Dict
|
3
|
+
|
4
|
+
@dataclass(frozen=True, kw_only=True)
|
5
|
+
class AbstractClassAttributes:
|
6
|
+
"""
|
7
|
+
A class to represent the attributes of an entity.
|
8
|
+
"""
|
9
|
+
public: Dict[str, Any]
|
10
|
+
private: Dict[str, Any]
|
11
|
+
protected: Dict[str, Any]
|
@@ -3,11 +3,11 @@ import ast
|
|
3
3
|
import inspect
|
4
4
|
import types
|
5
5
|
from typing import Any, Callable, Dict, List, Optional, Set, Tuple, Type, TypeVar
|
6
|
-
from orionis.luminate.support.introspection.
|
6
|
+
from orionis.luminate.support.introspection.abstracts.entities.abstract_class_attributes import AbstractClassAttributes
|
7
7
|
|
8
8
|
ABC = TypeVar('ABC', bound=abc.ABC)
|
9
9
|
|
10
|
-
class ReflexionAbstract
|
10
|
+
class ReflexionAbstract:
|
11
11
|
"""A reflection object encapsulating an abstract class.
|
12
12
|
|
13
13
|
Parameters
|
@@ -64,7 +64,7 @@ class ReflexionAbstract(IReflexionAbstract):
|
|
64
64
|
"""
|
65
65
|
return self._abstract.__module__
|
66
66
|
|
67
|
-
def getAllAttributes(self) ->
|
67
|
+
def getAllAttributes(self) -> AbstractClassAttributes:
|
68
68
|
"""
|
69
69
|
Get all attributes of the abstract class.
|
70
70
|
|
@@ -93,11 +93,161 @@ class ReflexionAbstract(IReflexionAbstract):
|
|
93
93
|
else:
|
94
94
|
public[attr] = value
|
95
95
|
|
96
|
-
return
|
96
|
+
return AbstractClassAttributes(
|
97
|
+
public=public,
|
98
|
+
private=private,
|
99
|
+
protected=protected
|
100
|
+
)
|
97
101
|
|
102
|
+
def getAttributes(self) -> Dict[str, Any]:
|
103
|
+
"""
|
104
|
+
Get all attributes of the instance.
|
98
105
|
|
106
|
+
Returns
|
107
|
+
-------
|
108
|
+
Dict[str, Any]
|
109
|
+
Dictionary of attribute names and their values
|
110
|
+
"""
|
111
|
+
attr = self.getAllAttributes()
|
112
|
+
return {**attr.public, **attr.private, **attr.protected}
|
99
113
|
|
114
|
+
def getPublicAttributes(self) -> Dict[str, Any]:
|
115
|
+
"""
|
116
|
+
Get all public attributes of the instance.
|
100
117
|
|
118
|
+
Returns
|
119
|
+
-------
|
120
|
+
Dict[str, Any]
|
121
|
+
Dictionary of public attribute names and their values
|
122
|
+
"""
|
123
|
+
attr = self.getAllAttributes()
|
124
|
+
return attr.public
|
125
|
+
|
126
|
+
def getPrivateAttributes(self) -> Dict[str, Any]:
|
127
|
+
"""
|
128
|
+
Get all private attributes of the instance.
|
129
|
+
|
130
|
+
Returns
|
131
|
+
-------
|
132
|
+
Dict[str, Any]
|
133
|
+
Dictionary of private attribute names and their values
|
134
|
+
"""
|
135
|
+
attr = self.getAllAttributes()
|
136
|
+
return attr.private
|
137
|
+
|
138
|
+
def getProtectedAttributes(self) -> Dict[str, Any]:
|
139
|
+
"""
|
140
|
+
Get all Protected attributes of the instance.
|
141
|
+
|
142
|
+
Returns
|
143
|
+
-------
|
144
|
+
Dict[str, Any]
|
145
|
+
Dictionary of Protected attribute names and their values
|
146
|
+
"""
|
147
|
+
attr = self.getAllAttributes()
|
148
|
+
return attr.protected
|
149
|
+
|
150
|
+
def getAllMethods(self) -> Dict[str, List[str]]:
|
151
|
+
"""
|
152
|
+
Categorize all methods and relevant members of the abstract class into public, private, protected,
|
153
|
+
static, asynchronous, synchronous, class methods, magic methods, abstract methods, and properties.
|
154
|
+
|
155
|
+
Returns
|
156
|
+
-------
|
157
|
+
Dict[str, List[str]]
|
158
|
+
A dictionary categorizing methods and attributes into various types.
|
159
|
+
"""
|
160
|
+
class_name = self.getClassName()
|
161
|
+
private_prefix = f"_{class_name}"
|
162
|
+
attributes = set(self.getAttributes().keys()) | {attr for attr in dir(self._abstract) if attr.startswith('_abc_')}
|
163
|
+
|
164
|
+
result = {
|
165
|
+
"public": [],
|
166
|
+
"private": [],
|
167
|
+
"protected": [],
|
168
|
+
"static": [],
|
169
|
+
"asynchronous": [],
|
170
|
+
"synchronous": [],
|
171
|
+
"class_methods": [],
|
172
|
+
"asynchronous_static": [],
|
173
|
+
"synchronous_static": [],
|
174
|
+
"magic": [],
|
175
|
+
"abstract": [],
|
176
|
+
"abstract_class_methods": [],
|
177
|
+
"abstract_static_methods": []
|
178
|
+
}
|
179
|
+
|
180
|
+
# Precompute all members once
|
181
|
+
members = inspect.getmembers(self._abstract)
|
182
|
+
static_attrs = {}
|
183
|
+
|
184
|
+
# First pass to collect all relevant information
|
185
|
+
for name, attr in members:
|
186
|
+
if name in attributes:
|
187
|
+
continue
|
188
|
+
|
189
|
+
# Get static attribute once
|
190
|
+
static_attr = inspect.getattr_static(self._abstract, name)
|
191
|
+
static_attrs[name] = static_attr
|
192
|
+
|
193
|
+
# Magic methods
|
194
|
+
if name.startswith("__") and name.endswith("__"):
|
195
|
+
result["magic"].append(name)
|
196
|
+
continue
|
197
|
+
|
198
|
+
# Static and class methods
|
199
|
+
if isinstance(static_attr, staticmethod):
|
200
|
+
result["static"].append(name)
|
201
|
+
elif isinstance(static_attr, classmethod):
|
202
|
+
result["class_methods"].append(name)
|
203
|
+
|
204
|
+
# Private, protected, public
|
205
|
+
if name.startswith(private_prefix):
|
206
|
+
clean_name = name.replace(private_prefix, "")
|
207
|
+
result["private"].append(clean_name)
|
208
|
+
elif name.startswith("_"):
|
209
|
+
result["protected"].append(name)
|
210
|
+
else:
|
211
|
+
result["public"].append(name)
|
212
|
+
|
213
|
+
# Async methods
|
214
|
+
if inspect.iscoroutinefunction(attr):
|
215
|
+
clean_name = name.replace(private_prefix, "")
|
216
|
+
if name in result["static"]:
|
217
|
+
result["asynchronous_static"].append(clean_name)
|
218
|
+
else:
|
219
|
+
result["asynchronous"].append(clean_name)
|
220
|
+
|
221
|
+
# Second pass for synchronous methods (needs info from first pass)
|
222
|
+
for name, attr in members:
|
223
|
+
if name in attributes or name in result["magic"] or name in result["class_methods"] or name in result["static"]:
|
224
|
+
continue
|
225
|
+
|
226
|
+
if inspect.isfunction(attr):
|
227
|
+
clean_name = name.replace(private_prefix, "")
|
228
|
+
if clean_name not in result["asynchronous"]:
|
229
|
+
result["synchronous"].append(clean_name)
|
230
|
+
|
231
|
+
# Synchronous static methods
|
232
|
+
for name in result["static"]:
|
233
|
+
if name not in attributes and name not in result["asynchronous_static"] and name not in result["class_methods"]:
|
234
|
+
result["synchronous_static"].append(name)
|
235
|
+
|
236
|
+
# Abstract methods
|
237
|
+
abstract_methods = getattr(self._abstract, "__abstractmethods__", set())
|
238
|
+
for name in abstract_methods:
|
239
|
+
if name in attributes:
|
240
|
+
continue
|
241
|
+
|
242
|
+
static_attr = static_attrs.get(name, inspect.getattr_static(self._abstract, name))
|
243
|
+
if isinstance(static_attr, staticmethod):
|
244
|
+
result["abstract_static_methods"].append(name)
|
245
|
+
elif isinstance(static_attr, classmethod):
|
246
|
+
result["abstract_class_methods"].append(name)
|
247
|
+
elif not isinstance(static_attr, property):
|
248
|
+
result["abstract"].append(name)
|
249
|
+
|
250
|
+
return result
|
101
251
|
|
102
252
|
|
103
253
|
|
@@ -109,19 +259,7 @@ class ReflexionAbstract(IReflexionAbstract):
|
|
109
259
|
|
110
260
|
|
111
261
|
|
112
|
-
def getAbstractMethods(self) -> Set[str]:
|
113
|
-
"""Get all abstract method names required by the class.
|
114
262
|
|
115
|
-
Returns
|
116
|
-
-------
|
117
|
-
Set[str]
|
118
|
-
Set of abstract method names
|
119
|
-
"""
|
120
|
-
methods = []
|
121
|
-
for method in self._abstract.__abstractmethods__:
|
122
|
-
if not isinstance(getattr(self._abstract, method), property):
|
123
|
-
methods.append(method)
|
124
|
-
return set(methods)
|
125
263
|
|
126
264
|
def getAbstractProperties(self) -> Set[str]:
|
127
265
|
"""Get all abstract property names required by the class.
|
@@ -171,8 +171,8 @@ class ReflectionInstance(IReflectionInstance):
|
|
171
171
|
def getAllMethods(self):
|
172
172
|
"""
|
173
173
|
Retrieves and categorizes all methods of the instance's class into various classifications.
|
174
|
-
This method inspects the instance's class and its methods, categorizing them into public, private,
|
175
|
-
protected, static, asynchronous, synchronous, class methods, asynchronous static, synchronous static,
|
174
|
+
This method inspects the instance's class and its methods, categorizing them into public, private,
|
175
|
+
protected, static, asynchronous, synchronous, class methods, asynchronous static, synchronous static,
|
176
176
|
and magic methods.
|
177
177
|
Returns
|
178
178
|
-------
|
@@ -10,4 +10,14 @@ __all__ = [
|
|
10
10
|
"AsyncTestCase",
|
11
11
|
"TestCase",
|
12
12
|
"SyncTestCase",
|
13
|
-
]
|
13
|
+
]
|
14
|
+
__author__ = "Raúl Mauricio Uñate Castro"
|
15
|
+
__description__ = (
|
16
|
+
"Orionis Framework - Component Test Suites is a microframework "
|
17
|
+
"for creating unit and integration tests. "
|
18
|
+
"It allows you to write tests quickly and easily, "
|
19
|
+
"using a clear and concise syntax. "
|
20
|
+
"Supports both asynchronous and synchronous tests, "
|
21
|
+
"as well as the creation of test suites and parallel test execution. "
|
22
|
+
"It uses Python's native unittest module for test creation."
|
23
|
+
)
|
@@ -6,17 +6,8 @@ class AsyncTestCase(unittest.IsolatedAsyncioTestCase, TestStdOut):
|
|
6
6
|
AsyncTestCase is a test case class designed for asynchronous unit testing.
|
7
7
|
It inherits from `unittest.IsolatedAsyncioTestCase` to provide support for
|
8
8
|
async test methods and `TestStdOut` for additional functionality.
|
9
|
-
Methods
|
10
|
-
-------
|
11
|
-
asyncSetUp()
|
12
|
-
Asynchronous setup method called before each test. It ensures that the
|
13
|
-
parent class's asyncSetUp method is invoked to initialize any required
|
14
|
-
resources.
|
15
|
-
asyncTearDown()
|
16
|
-
Asynchronous teardown method called after each test. It ensures that the
|
17
|
-
parent class's asyncTearDown method is invoked to clean up any resources
|
18
|
-
used during the test.
|
19
9
|
"""
|
10
|
+
|
20
11
|
async def asyncSetUp(self):
|
21
12
|
"""
|
22
13
|
Asynchronous setup method called before each test.
|
@@ -3,9 +3,14 @@ from orionis.luminate.test.output.test_std_out import TestStdOut
|
|
3
3
|
|
4
4
|
class TestCase(unittest.IsolatedAsyncioTestCase, TestStdOut):
|
5
5
|
"""
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
A base test case class for asynchronous unit tests.
|
7
|
+
Inherits from:
|
8
|
+
unittest.IsolatedAsyncioTestCase: Provides support for asynchronous test methods and setup/teardown.
|
9
|
+
TestStdOut: Mixin for capturing or testing standard output during tests.
|
10
|
+
This class defines asynchronous setup and teardown methods to ensure proper initialization and cleanup
|
11
|
+
of resources before and after each test case.
|
12
|
+
"""
|
13
|
+
|
9
14
|
async def asyncSetUp(self):
|
10
15
|
"""
|
11
16
|
Asynchronous setup method called before each test.
|
@@ -1,42 +1,30 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
+
from orionis.luminate.config.entities.testing import Testing
|
3
|
+
from orionis.luminate.test.core.test_unit import UnitTest
|
2
4
|
|
3
5
|
class ITestSuite(ABC):
|
4
6
|
"""
|
5
|
-
|
7
|
+
Interface for configuring and initializing a UnitTest suite using a provided Testing configuration.
|
8
|
+
Methods:
|
9
|
+
config(config: Testing) -> UnitTest:
|
6
10
|
"""
|
7
11
|
|
8
12
|
@staticmethod
|
9
13
|
@abstractmethod
|
10
|
-
def
|
11
|
-
base_path: str = 'tests',
|
12
|
-
folder_path: list | str = '*',
|
13
|
-
pattern: str = 'test_*.py'
|
14
|
-
):
|
14
|
+
def config(config:Testing) -> UnitTest:
|
15
15
|
"""
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
File pattern to match test files. Defaults to 'test_*.py'.
|
30
|
-
|
31
|
-
Returns
|
32
|
-
-------
|
33
|
-
UnitTestClass
|
34
|
-
An initialized test suite containing the discovered test files.
|
35
|
-
|
36
|
-
Raises
|
37
|
-
------
|
38
|
-
TypeError
|
39
|
-
If `base_path` is not a string, `folder_path` is not a string or list, or
|
40
|
-
`pattern` is not a string.
|
16
|
+
Configures and initializes a UnitTest suite based on the provided Testing configuration.
|
17
|
+
Args:
|
18
|
+
config (Testing): An instance of the Testing class containing configuration options for the test suite.
|
19
|
+
Returns:
|
20
|
+
UnitTest: An initialized UnitTest suite configured according to the provided settings.
|
21
|
+
Raises:
|
22
|
+
OrionisTestConfigException: If the config parameter is not an instance of the Testing class.
|
23
|
+
The function performs the following steps:
|
24
|
+
- Validates the type of the config parameter.
|
25
|
+
- Initializes a UnitTest suite and applies configuration values from the Testing instance.
|
26
|
+
- Discovers folders containing test files based on the specified base path, folder path(s), and filename pattern.
|
27
|
+
- Adds discovered test folders to the UnitTest suite, applying optional test name patterns and tags.
|
28
|
+
- Returns the configured UnitTest suite ready for execution.
|
41
29
|
"""
|
42
30
|
pass
|