orionis 0.443.0__py3-none-any.whl → 0.444.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/console/args/argument.py +343 -0
- orionis/console/args/enums/__init__.py +0 -0
- orionis/console/args/enums/actions.py +43 -0
- orionis/console/commands/version.py +19 -4
- orionis/foundation/providers/testing_provider.py +39 -2
- orionis/metadata/framework.py +1 -1
- orionis/test/core/unit_test.py +134 -5
- orionis/test/kernel.py +30 -83
- orionis/test/validators/workers.py +2 -2
- {orionis-0.443.0.dist-info → orionis-0.444.0.dist-info}/METADATA +1 -1
- {orionis-0.443.0.dist-info → orionis-0.444.0.dist-info}/RECORD +17 -14
- /orionis/console/{arguments → args}/__init__.py +0 -0
- /orionis/console/{arguments → args}/parser.py +0 -0
- {orionis-0.443.0.dist-info → orionis-0.444.0.dist-info}/WHEEL +0 -0
- {orionis-0.443.0.dist-info → orionis-0.444.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.443.0.dist-info → orionis-0.444.0.dist-info}/top_level.txt +0 -0
- {orionis-0.443.0.dist-info → orionis-0.444.0.dist-info}/zip-safe +0 -0
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
from dataclasses import dataclass, field
|
|
3
|
+
from typing import Any, Optional, List, Type, Union, Dict
|
|
4
|
+
from orionis.console.args.enums.actions import ArgumentAction
|
|
5
|
+
from orionis.console.exceptions.cli_orionis_value_error import CLIOrionisValueError
|
|
6
|
+
|
|
7
|
+
@dataclass(kw_only=True, frozen=True, slots=True)
|
|
8
|
+
class CLIArgument:
|
|
9
|
+
"""
|
|
10
|
+
Represents a command-line argument for argparse.
|
|
11
|
+
|
|
12
|
+
This class encapsulates all the properties and validation logic needed to create
|
|
13
|
+
a command-line argument that can be added to an argparse ArgumentParser. It provides
|
|
14
|
+
automatic validation, type checking, and smart defaults for common argument patterns.
|
|
15
|
+
|
|
16
|
+
Attributes
|
|
17
|
+
----------
|
|
18
|
+
flags : List[str]
|
|
19
|
+
List of flags for the argument (e.g., ['--export', '-e']). Must contain at least one flag.
|
|
20
|
+
type : Type
|
|
21
|
+
Data type of the argument. Can be any Python type or custom type.
|
|
22
|
+
help : str
|
|
23
|
+
Description of the argument. If not provided, will be auto-generated from the primary flag.
|
|
24
|
+
default : Any, optional
|
|
25
|
+
Default value for the argument.
|
|
26
|
+
choices : List[Any], optional
|
|
27
|
+
List of valid values for the argument. All choices must match the specified type.
|
|
28
|
+
required : bool, default False
|
|
29
|
+
Whether the argument is required. Only applies to optional arguments.
|
|
30
|
+
metavar : str, optional
|
|
31
|
+
Metavar for displaying in help messages. Auto-generated from primary flag if not provided.
|
|
32
|
+
dest : str, optional
|
|
33
|
+
Destination name for the argument in the namespace. Auto-generated from primary flag if not provided.
|
|
34
|
+
action : Union[str, ArgumentAction], default ArgumentAction.STORE
|
|
35
|
+
Action to perform with the argument when it's encountered.
|
|
36
|
+
nargs : Union[int, str], optional
|
|
37
|
+
Number of arguments expected (e.g., 1, 2, '+', '*').
|
|
38
|
+
const : Any, optional
|
|
39
|
+
Constant value for store_const or append_const actions.
|
|
40
|
+
|
|
41
|
+
Raises
|
|
42
|
+
------
|
|
43
|
+
CLIOrionisValueError
|
|
44
|
+
If any validation fails during initialization.
|
|
45
|
+
"""
|
|
46
|
+
|
|
47
|
+
# Required fields
|
|
48
|
+
flags: List[str] = None
|
|
49
|
+
type: Type = None
|
|
50
|
+
help: str = None
|
|
51
|
+
|
|
52
|
+
default: Any = field(
|
|
53
|
+
default_factory = None,
|
|
54
|
+
metadata = {
|
|
55
|
+
"description": "Default value for the argument.",
|
|
56
|
+
"default": None
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
choices: Optional[List[Any]] = field(
|
|
61
|
+
default_factory = None,
|
|
62
|
+
metadata = {
|
|
63
|
+
"description": "List of valid choices for the argument.",
|
|
64
|
+
"default": None
|
|
65
|
+
}
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
required: bool = field(
|
|
69
|
+
default_factory = False,
|
|
70
|
+
metadata = {
|
|
71
|
+
"description": "Indicates if the argument is required.",
|
|
72
|
+
"default": False
|
|
73
|
+
}
|
|
74
|
+
)
|
|
75
|
+
|
|
76
|
+
metavar: Optional[str] = field(
|
|
77
|
+
default_factory = None,
|
|
78
|
+
metadata = {
|
|
79
|
+
"description": "Metavar for displaying in help messages.",
|
|
80
|
+
"default": None
|
|
81
|
+
}
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
dest: Optional[str] = field(
|
|
85
|
+
default_factory = None,
|
|
86
|
+
metadata = {
|
|
87
|
+
"description": "Destination name for the argument in the namespace.",
|
|
88
|
+
"default": None
|
|
89
|
+
}
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
action: Union[str, ArgumentAction] = field(
|
|
93
|
+
default_factory = ArgumentAction.STORE,
|
|
94
|
+
metadata = {
|
|
95
|
+
"description": "Action to perform with the argument.",
|
|
96
|
+
"default": ArgumentAction.STORE.value
|
|
97
|
+
}
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
nargs: Optional[Union[int, str]] = field(
|
|
101
|
+
default_factory = None,
|
|
102
|
+
metadata = {
|
|
103
|
+
"description": "Number of arguments expected (e.g., 1, 2, '+', '*').",
|
|
104
|
+
"default": None
|
|
105
|
+
}
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
const: Any = field(
|
|
109
|
+
default_factory = None,
|
|
110
|
+
metadata = {
|
|
111
|
+
"description": "Constant value for store_const or append_const actions.",
|
|
112
|
+
"default": None
|
|
113
|
+
}
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
def __post_init__(self):
|
|
117
|
+
"""
|
|
118
|
+
Validate and normalize all argument attributes after initialization.
|
|
119
|
+
|
|
120
|
+
This method performs comprehensive validation of all argument attributes
|
|
121
|
+
and applies smart defaults where appropriate. It ensures the argument
|
|
122
|
+
configuration is valid for use with argparse.
|
|
123
|
+
|
|
124
|
+
Raises
|
|
125
|
+
------
|
|
126
|
+
CLIOrionisValueError
|
|
127
|
+
If any validation fails or invalid values are provided.
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
# Validate flags - must be provided and non-empty
|
|
131
|
+
if not self.flags:
|
|
132
|
+
raise CLIOrionisValueError(
|
|
133
|
+
"Flags list cannot be empty. Please provide at least one flag (e.g., ['--export', '-e'])"
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
# Convert single string flag to list for consistency
|
|
137
|
+
if isinstance(self.flags, str):
|
|
138
|
+
object.__setattr__(self, 'flags', [self.flags])
|
|
139
|
+
|
|
140
|
+
# Ensure flags is a list
|
|
141
|
+
if not isinstance(self.flags, list):
|
|
142
|
+
raise CLIOrionisValueError("Flags must be a string or a list of strings")
|
|
143
|
+
|
|
144
|
+
# Validate each flag format and ensure they're strings
|
|
145
|
+
for flag in self.flags:
|
|
146
|
+
if not isinstance(flag, str):
|
|
147
|
+
raise CLIOrionisValueError("All flags must be strings")
|
|
148
|
+
|
|
149
|
+
# Check for duplicate flags
|
|
150
|
+
if len(set(self.flags)) != len(self.flags):
|
|
151
|
+
raise CLIOrionisValueError("Duplicate flags are not allowed in the flags list")
|
|
152
|
+
|
|
153
|
+
# Determine primary flag (longest one, or first if only one)
|
|
154
|
+
primary_flag = max(self.flags, key=len) if len(self.flags) > 1 else self.flags[0]
|
|
155
|
+
|
|
156
|
+
# Validate type is actually a type
|
|
157
|
+
if not isinstance(self.type, type):
|
|
158
|
+
raise CLIOrionisValueError("Type must be a valid Python type or custom type class")
|
|
159
|
+
|
|
160
|
+
# Auto-generate help if not provided
|
|
161
|
+
if self.help is None:
|
|
162
|
+
object.__setattr__(self, 'help', f"Argument for {primary_flag}")
|
|
163
|
+
|
|
164
|
+
# Ensure help is a string
|
|
165
|
+
if not isinstance(self.help, str):
|
|
166
|
+
raise CLIOrionisValueError("Help text must be a string")
|
|
167
|
+
|
|
168
|
+
# Validate choices if provided
|
|
169
|
+
if self.choices is not None:
|
|
170
|
+
# Ensure choices is a list
|
|
171
|
+
if not isinstance(self.choices, list):
|
|
172
|
+
raise CLIOrionisValueError("Choices must be provided as a list")
|
|
173
|
+
|
|
174
|
+
# Ensure all choices match the specified type
|
|
175
|
+
if self.type and not all(isinstance(choice, self.type) for choice in self.choices):
|
|
176
|
+
raise CLIOrionisValueError(
|
|
177
|
+
f"All choices must be of type {self.type.__name__}"
|
|
178
|
+
)
|
|
179
|
+
|
|
180
|
+
# Validate required is boolean
|
|
181
|
+
if not isinstance(self.required, bool):
|
|
182
|
+
raise CLIOrionisValueError("Required field must be a boolean value (True or False)")
|
|
183
|
+
|
|
184
|
+
# Auto-generate metavar if not provided
|
|
185
|
+
if self.metavar is None:
|
|
186
|
+
metavar = primary_flag.lstrip('-').upper().replace('-', '_')
|
|
187
|
+
object.__setattr__(self, 'metavar', metavar)
|
|
188
|
+
|
|
189
|
+
# Ensure metavar is a string
|
|
190
|
+
if not isinstance(self.metavar, str):
|
|
191
|
+
raise CLIOrionisValueError("Metavar must be a string")
|
|
192
|
+
|
|
193
|
+
# Auto-generate dest if not provided
|
|
194
|
+
if self.dest is None:
|
|
195
|
+
dest = primary_flag.lstrip('-').replace('-', '_')
|
|
196
|
+
object.__setattr__(self, 'dest', dest)
|
|
197
|
+
|
|
198
|
+
# Ensure dest is a string
|
|
199
|
+
if not isinstance(self.dest, str):
|
|
200
|
+
raise CLIOrionisValueError("Destination (dest) must be a string")
|
|
201
|
+
|
|
202
|
+
# Ensure dest is a valid Python identifier
|
|
203
|
+
if not self.dest.isidentifier():
|
|
204
|
+
raise CLIOrionisValueError(f"Destination '{self.dest}' is not a valid Python identifier")
|
|
205
|
+
|
|
206
|
+
# Normalize action value
|
|
207
|
+
if self.action is None:
|
|
208
|
+
object.__setattr__(self, 'action', ArgumentAction.STORE.value)
|
|
209
|
+
elif isinstance(self.action, str):
|
|
210
|
+
try:
|
|
211
|
+
action_enum = ArgumentAction(self.action)
|
|
212
|
+
object.__setattr__(self, 'action', action_enum.value)
|
|
213
|
+
except ValueError:
|
|
214
|
+
raise CLIOrionisValueError(f"Invalid action '{self.action}'. Please use a valid ArgumentAction value")
|
|
215
|
+
elif isinstance(self.action, ArgumentAction):
|
|
216
|
+
object.__setattr__(self, 'action', self.action.value)
|
|
217
|
+
else:
|
|
218
|
+
raise CLIOrionisValueError("Action must be a string or an ArgumentAction enum value")
|
|
219
|
+
|
|
220
|
+
# Special handling for boolean types
|
|
221
|
+
if self.type is bool:
|
|
222
|
+
|
|
223
|
+
# Auto-configure action based on default value
|
|
224
|
+
action = ArgumentAction.STORE_TRUE.value if not self.default else ArgumentAction.STORE_FALSE.value
|
|
225
|
+
object.__setattr__(self, 'action', action)
|
|
226
|
+
|
|
227
|
+
# argparse ignores type with store_true/false actions
|
|
228
|
+
object.__setattr__(self, 'type', None)
|
|
229
|
+
|
|
230
|
+
# Special handling for list types
|
|
231
|
+
if self.type is list and self.nargs is None:
|
|
232
|
+
|
|
233
|
+
# Auto-configure for accepting multiple values
|
|
234
|
+
object.__setattr__(self, 'nargs', '+')
|
|
235
|
+
object.__setattr__(self, 'type', str)
|
|
236
|
+
|
|
237
|
+
def addToParser(self, parser: argparse.ArgumentParser) -> None:
|
|
238
|
+
"""
|
|
239
|
+
Add this argument to an argparse ArgumentParser instance.
|
|
240
|
+
|
|
241
|
+
This method integrates the CLIArgument configuration with an argparse
|
|
242
|
+
ArgumentParser by building the appropriate keyword arguments and adding
|
|
243
|
+
the argument with all its flags and options. The method handles all
|
|
244
|
+
necessary conversions and validations to ensure compatibility with
|
|
245
|
+
argparse's expected format.
|
|
246
|
+
|
|
247
|
+
Parameters
|
|
248
|
+
----------
|
|
249
|
+
parser : argparse.ArgumentParser
|
|
250
|
+
The ArgumentParser instance to which this argument will be added.
|
|
251
|
+
The parser must be a valid argparse.ArgumentParser object.
|
|
252
|
+
|
|
253
|
+
Returns
|
|
254
|
+
-------
|
|
255
|
+
None
|
|
256
|
+
This method does not return any value. It modifies the provided
|
|
257
|
+
parser by adding the argument configuration to it.
|
|
258
|
+
|
|
259
|
+
Raises
|
|
260
|
+
------
|
|
261
|
+
CLIOrionisValueError
|
|
262
|
+
If there's an error adding the argument to the parser, such as
|
|
263
|
+
conflicting argument names, invalid configurations, or argparse
|
|
264
|
+
internal errors during argument registration.
|
|
265
|
+
"""
|
|
266
|
+
|
|
267
|
+
# Build the keyword arguments dictionary for argparse compatibility
|
|
268
|
+
# This filters out None values and handles special argument types
|
|
269
|
+
kwargs = self._buildParserKwargs()
|
|
270
|
+
|
|
271
|
+
# Attempt to add the argument to the parser with all flags and options
|
|
272
|
+
try:
|
|
273
|
+
# Use unpacking to pass all flags as positional arguments
|
|
274
|
+
# and all configuration options as keyword arguments
|
|
275
|
+
parser.add_argument(*self.flags, **kwargs)
|
|
276
|
+
|
|
277
|
+
# Catch any exception that occurs during argument addition
|
|
278
|
+
# and wrap it in our custom exception for consistent error handling
|
|
279
|
+
except Exception as e:
|
|
280
|
+
raise CLIOrionisValueError(f"Error adding argument {self.flags}: {e}")
|
|
281
|
+
|
|
282
|
+
def _buildParserKwargs(self) -> Dict[str, Any]:
|
|
283
|
+
"""
|
|
284
|
+
Build the keyword arguments dictionary for argparse compatibility.
|
|
285
|
+
|
|
286
|
+
This private method constructs a dictionary of keyword arguments that will be
|
|
287
|
+
passed to argparse's add_argument method. It handles the conversion from
|
|
288
|
+
CLIArgument attributes to argparse-compatible parameters, filtering out None
|
|
289
|
+
values and applying special handling for different argument types (optional
|
|
290
|
+
vs positional arguments).
|
|
291
|
+
|
|
292
|
+
The method ensures that the resulting kwargs dictionary contains only valid
|
|
293
|
+
argparse parameters with appropriate values, preventing errors during argument
|
|
294
|
+
registration with the ArgumentParser.
|
|
295
|
+
|
|
296
|
+
Returns
|
|
297
|
+
-------
|
|
298
|
+
Dict[str, Any]
|
|
299
|
+
A dictionary containing keyword arguments ready to be unpacked and passed
|
|
300
|
+
to argparse.ArgumentParser.add_argument(). The dictionary includes only
|
|
301
|
+
non-None values and excludes parameters that are invalid for the specific
|
|
302
|
+
argument type (e.g., 'required' parameter for positional arguments).
|
|
303
|
+
|
|
304
|
+
Notes
|
|
305
|
+
-----
|
|
306
|
+
This method distinguishes between optional arguments (those starting with '-')
|
|
307
|
+
and positional arguments, applying different validation rules for each type.
|
|
308
|
+
Positional arguments cannot use the 'required' parameter, so it's automatically
|
|
309
|
+
removed from the kwargs if present.
|
|
310
|
+
"""
|
|
311
|
+
|
|
312
|
+
# Determine argument type by checking if any flag starts with a dash
|
|
313
|
+
# Optional arguments have flags like '--export' or '-e'
|
|
314
|
+
# Positional arguments have flags without dashes like 'filename'
|
|
315
|
+
is_optional = any(flag.startswith('-') for flag in self.flags)
|
|
316
|
+
is_positional = not is_optional
|
|
317
|
+
|
|
318
|
+
# Build the base kwargs dictionary with all possible argparse parameters
|
|
319
|
+
# Each key corresponds to a parameter accepted by argparse.add_argument()
|
|
320
|
+
kwargs = {
|
|
321
|
+
"help": self.help, # Help text displayed in usage messages
|
|
322
|
+
"default": self.default, # Default value when argument not provided
|
|
323
|
+
"required": self.required and is_optional, # Whether argument is mandatory
|
|
324
|
+
"metavar": self.metavar, # Name displayed in help messages
|
|
325
|
+
"dest": self.dest, # Attribute name in the parsed namespace
|
|
326
|
+
"choices": self.choices, # List of valid values for the argument
|
|
327
|
+
"action": self.action, # Action to take when argument is encountered
|
|
328
|
+
"nargs": self.nargs, # Number of command-line arguments expected
|
|
329
|
+
"type": self.type, # Type to convert the argument to
|
|
330
|
+
"const": self.const # Constant value for certain actions
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
# Filter out None values to prevent passing invalid parameters to argparse
|
|
334
|
+
# argparse will raise errors if None values are explicitly passed for certain parameters
|
|
335
|
+
kwargs = {k: v for k, v in kwargs.items() if v is not None}
|
|
336
|
+
|
|
337
|
+
# Remove 'required' parameter for positional arguments since it's not supported
|
|
338
|
+
# Positional arguments are inherently required by argparse's design
|
|
339
|
+
if is_positional and 'required' in kwargs:
|
|
340
|
+
del kwargs['required']
|
|
341
|
+
|
|
342
|
+
# Return the cleaned and validated kwargs dictionary
|
|
343
|
+
return kwargs
|
|
File without changes
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
from enum import Enum
|
|
2
|
+
|
|
3
|
+
class ArgumentAction(Enum):
|
|
4
|
+
"""
|
|
5
|
+
Enumeration for valid argparse action types.
|
|
6
|
+
|
|
7
|
+
This enum provides a comprehensive list of all standard action types
|
|
8
|
+
that can be used with Python's argparse module when defining command
|
|
9
|
+
line arguments. Each enum member corresponds to a specific behavior
|
|
10
|
+
for how argument values should be processed and stored.
|
|
11
|
+
|
|
12
|
+
Returns
|
|
13
|
+
-------
|
|
14
|
+
str
|
|
15
|
+
The string value representing the argparse action type.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
# Store the argument value directly
|
|
19
|
+
STORE = "store"
|
|
20
|
+
|
|
21
|
+
# Store a constant value when the argument is specified
|
|
22
|
+
STORE_CONST = "store_const"
|
|
23
|
+
|
|
24
|
+
# Store True when the argument is specified
|
|
25
|
+
STORE_TRUE = "store_true"
|
|
26
|
+
|
|
27
|
+
# Store False when the argument is specified
|
|
28
|
+
STORE_FALSE = "store_false"
|
|
29
|
+
|
|
30
|
+
# Append each argument value to a list
|
|
31
|
+
APPEND = "append"
|
|
32
|
+
|
|
33
|
+
# Append a constant value to a list when the argument is specified
|
|
34
|
+
APPEND_CONST = "append_const"
|
|
35
|
+
|
|
36
|
+
# Count the number of times the argument is specified
|
|
37
|
+
COUNT = "count"
|
|
38
|
+
|
|
39
|
+
# Display help message and exit
|
|
40
|
+
HELP = "help"
|
|
41
|
+
|
|
42
|
+
# Display version information and exit
|
|
43
|
+
VERSION = "version"
|
|
@@ -15,17 +15,32 @@ class VersionCommand(BaseCommand):
|
|
|
15
15
|
|
|
16
16
|
def handle(self) -> None:
|
|
17
17
|
"""
|
|
18
|
-
|
|
18
|
+
Executes the version command to display the current Orionis framework version.
|
|
19
19
|
|
|
20
|
-
This method retrieves
|
|
20
|
+
This method retrieves the version number from the framework metadata and prints it
|
|
21
|
+
in a formatted, bold, and successful style to the console. If an unexpected error occurs
|
|
22
|
+
during execution, it raises a CLIOrionisRuntimeError with the original exception message.
|
|
23
|
+
|
|
24
|
+
Parameters
|
|
25
|
+
----------
|
|
26
|
+
None
|
|
27
|
+
|
|
28
|
+
Returns
|
|
29
|
+
-------
|
|
30
|
+
None
|
|
31
|
+
This method does not return any value. It outputs the version information to the console.
|
|
21
32
|
|
|
22
33
|
Raises
|
|
23
34
|
------
|
|
24
|
-
|
|
25
|
-
If an unexpected error occurs during execution, a
|
|
35
|
+
CLIOrionisRuntimeError
|
|
36
|
+
If an unexpected error occurs during execution, a CLIOrionisRuntimeError is raised
|
|
26
37
|
with the original exception message.
|
|
27
38
|
"""
|
|
39
|
+
|
|
40
|
+
# Print the Orionis framework version in a bold, success style
|
|
28
41
|
try:
|
|
29
42
|
self.textSuccessBold(f"Orionis Framework v{VERSION}")
|
|
43
|
+
|
|
44
|
+
# Raise a custom runtime error if any exception occurs
|
|
30
45
|
except Exception as e:
|
|
31
46
|
raise CLIOrionisRuntimeError(f"An unexpected error occurred: {e}") from e
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
from orionis.container.providers.service_provider import ServiceProvider
|
|
2
2
|
from orionis.test.contracts.unit_test import IUnitTest
|
|
3
3
|
from orionis.test.core.unit_test import UnitTest
|
|
4
|
+
from orionis.foundation.config.testing.entities.testing import Testing
|
|
5
|
+
import os
|
|
4
6
|
|
|
5
7
|
class TestingProvider(ServiceProvider):
|
|
6
8
|
"""
|
|
@@ -28,7 +30,39 @@ class TestingProvider(ServiceProvider):
|
|
|
28
30
|
None
|
|
29
31
|
"""
|
|
30
32
|
|
|
31
|
-
|
|
33
|
+
# Create a Testing configuration instance from the application config
|
|
34
|
+
config = Testing(**self.app.config('testing'))
|
|
35
|
+
|
|
36
|
+
# Create a UnitTest instance
|
|
37
|
+
unit_test = UnitTest(
|
|
38
|
+
app=self.app,
|
|
39
|
+
storage=self.app.path('storage_testing')
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# Configure the UnitTest instance with settings from the Testing configuration
|
|
43
|
+
unit_test.configure(
|
|
44
|
+
verbosity=config.verbosity,
|
|
45
|
+
execution_mode=config.execution_mode,
|
|
46
|
+
max_workers=config.max_workers,
|
|
47
|
+
fail_fast=config.fail_fast,
|
|
48
|
+
print_result=config.print_result,
|
|
49
|
+
throw_exception=config.throw_exception,
|
|
50
|
+
persistent=config.persistent,
|
|
51
|
+
persistent_driver=config.persistent_driver,
|
|
52
|
+
web_report=config.web_report
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Discover tests based on the configuration
|
|
56
|
+
unit_test.discoverTests(
|
|
57
|
+
base_path=config.base_path,
|
|
58
|
+
folder_path=config.folder_path,
|
|
59
|
+
pattern=config.pattern,
|
|
60
|
+
test_name_pattern=config.test_name_pattern,
|
|
61
|
+
tags=config.tags
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
# Register the UnitTest instance in the application container
|
|
65
|
+
self.app.instance(IUnitTest, unit_test, alias="core.orionis.testing")
|
|
32
66
|
|
|
33
67
|
def boot(self) -> None:
|
|
34
68
|
"""
|
|
@@ -42,4 +76,7 @@ class TestingProvider(ServiceProvider):
|
|
|
42
76
|
None
|
|
43
77
|
"""
|
|
44
78
|
|
|
45
|
-
|
|
79
|
+
# Ensure directory for testing storage exists
|
|
80
|
+
storage_path = self.app.path('storage_testing')
|
|
81
|
+
if not os.path.exists(storage_path):
|
|
82
|
+
os.makedirs(storage_path, exist_ok=True)
|
orionis/metadata/framework.py
CHANGED
orionis/test/core/unit_test.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import io
|
|
2
2
|
import json
|
|
3
|
+
from os import walk
|
|
3
4
|
import re
|
|
4
5
|
import time
|
|
5
6
|
import traceback
|
|
@@ -9,6 +10,7 @@ from contextlib import redirect_stdout, redirect_stderr
|
|
|
9
10
|
from datetime import datetime
|
|
10
11
|
from pathlib import Path
|
|
11
12
|
from typing import Any, Dict, List, Optional, Tuple
|
|
13
|
+
from orionis.app import Orionis
|
|
12
14
|
from orionis.container.resolver.resolver import Resolver
|
|
13
15
|
from orionis.foundation.config.testing.enums.drivers import PersistentDrivers
|
|
14
16
|
from orionis.foundation.config.testing.enums.mode import ExecutionMode
|
|
@@ -102,7 +104,9 @@ class UnitTest(IUnitTest):
|
|
|
102
104
|
"""
|
|
103
105
|
|
|
104
106
|
def __init__(
|
|
105
|
-
self
|
|
107
|
+
self,
|
|
108
|
+
app: Optional[IApplication] = None,
|
|
109
|
+
storage: Optional[str] = None
|
|
106
110
|
) -> None:
|
|
107
111
|
"""
|
|
108
112
|
Initialize a UnitTest instance with default configuration and internal state.
|
|
@@ -113,11 +117,11 @@ class UnitTest(IUnitTest):
|
|
|
113
117
|
-------
|
|
114
118
|
None
|
|
115
119
|
"""
|
|
116
|
-
# Application instance for dependency injection
|
|
117
|
-
self.__app: Optional[IApplication] =
|
|
120
|
+
# Application instance for dependency injection
|
|
121
|
+
self.__app: Optional[IApplication] = app or Orionis()
|
|
118
122
|
|
|
119
|
-
# Storage path for test results
|
|
120
|
-
self.__storage: Optional[str] =
|
|
123
|
+
# Storage path for test results
|
|
124
|
+
self.__storage: Optional[str] = storage or self.__app.path('storage_testing')
|
|
121
125
|
|
|
122
126
|
# Configuration values (set via configure)
|
|
123
127
|
self.__verbosity: Optional[int] = None
|
|
@@ -220,6 +224,100 @@ class UnitTest(IUnitTest):
|
|
|
220
224
|
# Return the instance to allow method chaining
|
|
221
225
|
return self
|
|
222
226
|
|
|
227
|
+
def discoverTests(
|
|
228
|
+
self,
|
|
229
|
+
base_path: str | Path,
|
|
230
|
+
folder_path: str | List[str],
|
|
231
|
+
pattern: str,
|
|
232
|
+
test_name_pattern: Optional[str] = None,
|
|
233
|
+
tags: Optional[List[str]] = None
|
|
234
|
+
) -> 'UnitTest':
|
|
235
|
+
"""
|
|
236
|
+
Discover test cases from specified folders using flexible path discovery.
|
|
237
|
+
|
|
238
|
+
This method provides a convenient way to discover and load test cases from multiple folders
|
|
239
|
+
based on various path specifications. It supports wildcard discovery, single folder loading,
|
|
240
|
+
and multiple folder loading. The method automatically resolves paths relative to the base
|
|
241
|
+
directory and discovers all folders containing files matching the specified pattern.
|
|
242
|
+
|
|
243
|
+
Parameters
|
|
244
|
+
----------
|
|
245
|
+
base_path : str or Path
|
|
246
|
+
Base directory path for resolving relative folder paths. This serves as the root
|
|
247
|
+
directory from which all folder searches are conducted.
|
|
248
|
+
folder_path : str or list of str
|
|
249
|
+
Specification of folders to search for test cases. Can be:
|
|
250
|
+
- '*' : Discover all folders containing matching files within base_path
|
|
251
|
+
- str : Single folder path relative to base_path
|
|
252
|
+
- list of str : Multiple folder paths relative to base_path
|
|
253
|
+
pattern : str
|
|
254
|
+
File name pattern to match test files, supporting wildcards (* and ?).
|
|
255
|
+
Examples: 'test_*.py', '*_test.py', 'test*.py'
|
|
256
|
+
test_name_pattern : str, optional
|
|
257
|
+
Regular expression pattern to filter test method names. Only tests whose
|
|
258
|
+
names match this pattern will be included. Default is None (no filtering).
|
|
259
|
+
tags : list of str, optional
|
|
260
|
+
List of tags to filter tests. Only tests decorated with matching tags
|
|
261
|
+
will be included. Default is None (no tag filtering).
|
|
262
|
+
|
|
263
|
+
Returns
|
|
264
|
+
-------
|
|
265
|
+
UnitTest
|
|
266
|
+
The current UnitTest instance with discovered tests added to the suite,
|
|
267
|
+
enabling method chaining.
|
|
268
|
+
|
|
269
|
+
Notes
|
|
270
|
+
-----
|
|
271
|
+
- All paths are resolved as absolute paths relative to the base_path
|
|
272
|
+
- When folder_path is '*', the method searches recursively through all subdirectories
|
|
273
|
+
- The method uses the existing discoverTestsInFolder method for actual test discovery
|
|
274
|
+
- Duplicate folders are automatically eliminated using a set data structure
|
|
275
|
+
- The method does not validate the existence of specified folders; validation
|
|
276
|
+
occurs during the actual test discovery process
|
|
277
|
+
"""
|
|
278
|
+
# Resolve the base path as an absolute path from the current working directory
|
|
279
|
+
base_path = (Path.cwd() / base_path).resolve()
|
|
280
|
+
|
|
281
|
+
# Use a set to store discovered folders and automatically eliminate duplicates
|
|
282
|
+
discovered_folders = set()
|
|
283
|
+
|
|
284
|
+
# Handle wildcard discovery: search all folders containing matching files
|
|
285
|
+
if folder_path == '*':
|
|
286
|
+
|
|
287
|
+
# Search recursively through the entire base path for folders with matching files
|
|
288
|
+
discovered_folders.update(self.__listMatchingFolders(base_path, base_path, pattern))
|
|
289
|
+
|
|
290
|
+
# Handle multiple folder paths: process each folder in the provided list
|
|
291
|
+
elif isinstance(folder_path, list):
|
|
292
|
+
for custom in folder_path:
|
|
293
|
+
# Resolve each custom folder path relative to the base path
|
|
294
|
+
custom_path = (base_path / custom).resolve()
|
|
295
|
+
# Add all matching folders found within this custom path
|
|
296
|
+
discovered_folders.update(self.__listMatchingFolders(base_path, custom_path, pattern))
|
|
297
|
+
|
|
298
|
+
# Handle single folder path: process the single specified folder
|
|
299
|
+
else:
|
|
300
|
+
|
|
301
|
+
# Resolve the single folder path relative to the base path
|
|
302
|
+
custom_path = (base_path / folder_path).resolve()
|
|
303
|
+
# Add all matching folders found within this single path
|
|
304
|
+
discovered_folders.update(self.__listMatchingFolders(base_path, custom_path, pattern))
|
|
305
|
+
|
|
306
|
+
# Iterate through all discovered folders and perform test discovery
|
|
307
|
+
for folder in discovered_folders:
|
|
308
|
+
|
|
309
|
+
# Use the existing discoverTestsInFolder method to actually discover and load tests
|
|
310
|
+
self.discoverTestsInFolder(
|
|
311
|
+
base_path=base_path,
|
|
312
|
+
folder_path=folder,
|
|
313
|
+
pattern=pattern,
|
|
314
|
+
test_name_pattern=test_name_pattern or None,
|
|
315
|
+
tags=tags or None
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
# Return the current instance to enable method chaining
|
|
319
|
+
return self
|
|
320
|
+
|
|
223
321
|
def discoverTestsInFolder(
|
|
224
322
|
self,
|
|
225
323
|
*,
|
|
@@ -1342,6 +1440,37 @@ class UnitTest(IUnitTest):
|
|
|
1342
1440
|
# Return the suite containing only the filtered tests
|
|
1343
1441
|
return filtered_suite
|
|
1344
1442
|
|
|
1443
|
+
def __listMatchingFolders(
|
|
1444
|
+
self,
|
|
1445
|
+
base_path: Path,
|
|
1446
|
+
custom_path: Path,
|
|
1447
|
+
pattern: str
|
|
1448
|
+
) -> List[str]:
|
|
1449
|
+
"""
|
|
1450
|
+
List folders within a given path containing files matching a pattern.
|
|
1451
|
+
|
|
1452
|
+
Parameters
|
|
1453
|
+
----------
|
|
1454
|
+
base_path : Path
|
|
1455
|
+
The base directory path for calculating relative paths.
|
|
1456
|
+
custom_path : Path
|
|
1457
|
+
The directory path to search for matching files.
|
|
1458
|
+
pattern : str
|
|
1459
|
+
The filename pattern to match, supporting '*' and '?' wildcards.
|
|
1460
|
+
|
|
1461
|
+
Returns
|
|
1462
|
+
-------
|
|
1463
|
+
List[str]
|
|
1464
|
+
List of relative folder paths containing files matching the pattern.
|
|
1465
|
+
"""
|
|
1466
|
+
regex = re.compile('^' + pattern.replace('*', '.*').replace('?', '.') + '$')
|
|
1467
|
+
matched_folders = set()
|
|
1468
|
+
for root, _, files in walk(str(custom_path)):
|
|
1469
|
+
if any(regex.fullmatch(file) for file in files):
|
|
1470
|
+
rel_path = Path(root).relative_to(base_path).as_posix()
|
|
1471
|
+
matched_folders.add(rel_path)
|
|
1472
|
+
return list(matched_folders)
|
|
1473
|
+
|
|
1345
1474
|
def getTestNames(
|
|
1346
1475
|
self
|
|
1347
1476
|
) -> List[str]:
|
orionis/test/kernel.py
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
import re
|
|
3
|
-
from typing import List
|
|
4
|
-
from os import walk
|
|
5
1
|
from orionis.console.output.contracts.console import IConsole
|
|
6
|
-
from orionis.foundation.config.testing.entities.testing import Testing
|
|
7
2
|
from orionis.foundation.contracts.application import IApplication
|
|
8
3
|
from orionis.test.contracts.kernel import ITestKernel
|
|
9
4
|
from orionis.test.contracts.unit_test import IUnitTest
|
|
@@ -18,115 +13,67 @@ class TestKernel(ITestKernel):
|
|
|
18
13
|
"""
|
|
19
14
|
Initialize the TestKernel with the provided application instance.
|
|
20
15
|
|
|
16
|
+
This constructor sets up the test kernel by validating the application
|
|
17
|
+
instance and resolving required dependencies for testing operations.
|
|
18
|
+
|
|
21
19
|
Parameters
|
|
22
20
|
----------
|
|
23
21
|
app : IApplication
|
|
24
|
-
|
|
22
|
+
The application instance that provides dependency injection
|
|
23
|
+
and service resolution capabilities.
|
|
25
24
|
|
|
26
25
|
Raises
|
|
27
26
|
------
|
|
28
27
|
OrionisTestConfigException
|
|
29
|
-
If the provided app is not an instance of IApplication.
|
|
28
|
+
If the provided app parameter is not an instance of IApplication.
|
|
29
|
+
|
|
30
|
+
Returns
|
|
31
|
+
-------
|
|
32
|
+
None
|
|
33
|
+
This is a constructor method and does not return a value.
|
|
30
34
|
"""
|
|
35
|
+
# Validate that the provided app parameter is an IApplication instance
|
|
31
36
|
if not isinstance(app, IApplication):
|
|
32
37
|
raise OrionisTestConfigException(
|
|
33
38
|
f"Failed to initialize TestKernel: expected IApplication, got {type(app).__module__}.{type(app).__name__}."
|
|
34
39
|
)
|
|
35
40
|
|
|
36
|
-
|
|
41
|
+
# Resolve the unit test service from the application container
|
|
37
42
|
self.__unit_test: IUnitTest = app.make('core.orionis.testing')
|
|
38
|
-
self.__unit_test._UnitTest__app = app
|
|
39
|
-
self.__unit_test._UnitTest__storage = app.path('storage_testing')
|
|
40
|
-
self.__console: IConsole = app.make('core.orionis.console')
|
|
41
|
-
|
|
42
|
-
def __listMatchingFolders(
|
|
43
|
-
self,
|
|
44
|
-
base_path: Path,
|
|
45
|
-
custom_path: Path,
|
|
46
|
-
pattern: str
|
|
47
|
-
) -> List[str]:
|
|
48
|
-
"""
|
|
49
|
-
List folders within a given path containing files matching a pattern.
|
|
50
|
-
|
|
51
|
-
Parameters
|
|
52
|
-
----------
|
|
53
|
-
base_path : Path
|
|
54
|
-
The base directory path for calculating relative paths.
|
|
55
|
-
custom_path : Path
|
|
56
|
-
The directory path to search for matching files.
|
|
57
|
-
pattern : str
|
|
58
|
-
The filename pattern to match, supporting '*' and '?' wildcards.
|
|
59
43
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
List[str]
|
|
63
|
-
List of relative folder paths containing files matching the pattern.
|
|
64
|
-
"""
|
|
65
|
-
regex = re.compile('^' + pattern.replace('*', '.*').replace('?', '.') + '$')
|
|
66
|
-
matched_folders = set()
|
|
67
|
-
for root, _, files in walk(str(custom_path)):
|
|
68
|
-
if any(regex.fullmatch(file) for file in files):
|
|
69
|
-
rel_path = Path(root).relative_to(base_path).as_posix()
|
|
70
|
-
matched_folders.add(rel_path)
|
|
71
|
-
return list(matched_folders)
|
|
44
|
+
# Resolve the console service from the application container
|
|
45
|
+
self.__console: IConsole = app.make('core.orionis.console')
|
|
72
46
|
|
|
73
47
|
def handle(self) -> IUnitTest:
|
|
74
48
|
"""
|
|
75
|
-
|
|
49
|
+
Execute the unit test suite and handle any exceptions that occur during testing.
|
|
50
|
+
|
|
51
|
+
This method serves as the main entry point for running tests through the test kernel.
|
|
52
|
+
It executes the unit test suite via the injected unit test service and provides
|
|
53
|
+
comprehensive error handling for both expected test failures and unexpected errors.
|
|
54
|
+
The method ensures graceful termination of the application in case of any failures.
|
|
76
55
|
|
|
77
56
|
Returns
|
|
78
57
|
-------
|
|
79
58
|
IUnitTest
|
|
80
|
-
The
|
|
59
|
+
The unit test service instance after successful test execution. This allows
|
|
60
|
+
for potential chaining of operations or access to test results.
|
|
81
61
|
|
|
82
62
|
Raises
|
|
83
63
|
------
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
If an unexpected error occurs during test execution.
|
|
64
|
+
SystemExit
|
|
65
|
+
Indirectly raised through console.exitError() when test failures or
|
|
66
|
+
unexpected errors occur during test execution.
|
|
88
67
|
"""
|
|
89
|
-
try:
|
|
90
|
-
self.__unit_test.configure(
|
|
91
|
-
verbosity=self.__config.verbosity,
|
|
92
|
-
execution_mode=self.__config.execution_mode,
|
|
93
|
-
max_workers=self.__config.max_workers,
|
|
94
|
-
fail_fast=self.__config.fail_fast,
|
|
95
|
-
print_result=self.__config.print_result,
|
|
96
|
-
throw_exception=self.__config.throw_exception,
|
|
97
|
-
persistent=self.__config.persistent,
|
|
98
|
-
persistent_driver=self.__config.persistent_driver,
|
|
99
|
-
web_report=self.__config.web_report
|
|
100
|
-
)
|
|
101
|
-
|
|
102
|
-
base_path = (Path.cwd() / self.__config.base_path).resolve()
|
|
103
|
-
folder_path = self.__config.folder_path
|
|
104
|
-
pattern = self.__config.pattern
|
|
105
|
-
discovered_folders = set()
|
|
106
|
-
|
|
107
|
-
if folder_path == '*':
|
|
108
|
-
discovered_folders.update(self.__listMatchingFolders(base_path, base_path, pattern))
|
|
109
|
-
elif isinstance(folder_path, list):
|
|
110
|
-
for custom in folder_path:
|
|
111
|
-
custom_path = (base_path / custom).resolve()
|
|
112
|
-
discovered_folders.update(self.__listMatchingFolders(base_path, custom_path, pattern))
|
|
113
|
-
else:
|
|
114
|
-
custom_path = (base_path / folder_path).resolve()
|
|
115
|
-
discovered_folders.update(self.__listMatchingFolders(base_path, custom_path, pattern))
|
|
116
|
-
|
|
117
|
-
for folder in discovered_folders:
|
|
118
|
-
self.__unit_test.discoverTestsInFolder(
|
|
119
|
-
folder_path=folder,
|
|
120
|
-
base_path=self.__config.base_path,
|
|
121
|
-
pattern=pattern,
|
|
122
|
-
test_name_pattern=self.__config.test_name_pattern or None,
|
|
123
|
-
tags=self.__config.tags or None
|
|
124
|
-
)
|
|
125
68
|
|
|
69
|
+
# Execute the unit test suite through the injected unit test service
|
|
70
|
+
try:
|
|
126
71
|
return self.__unit_test.run()
|
|
127
72
|
|
|
73
|
+
# Handle expected test failures with a descriptive error message
|
|
128
74
|
except OrionisTestFailureException as e:
|
|
129
75
|
self.__console.exitError(f"Test execution failed: {e}")
|
|
130
76
|
|
|
77
|
+
# Handle any unexpected errors that occur during test execution
|
|
131
78
|
except Exception as e:
|
|
132
79
|
self.__console.exitError(f"An unexpected error occurred: {e}")
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from orionis.
|
|
1
|
+
from orionis.services.system.workers import Workers
|
|
2
2
|
from orionis.test.exceptions import OrionisTestValueError
|
|
3
3
|
|
|
4
4
|
class __ValidWorkers:
|
|
@@ -25,7 +25,7 @@ class __ValidWorkers:
|
|
|
25
25
|
OrionisTestValueError
|
|
26
26
|
If `max_workers` is not a positive integer within the allowed range.
|
|
27
27
|
"""
|
|
28
|
-
max_allowed = Workers.calculate()
|
|
28
|
+
max_allowed = Workers().calculate()
|
|
29
29
|
if not isinstance(max_workers, int) or max_workers < 1 or max_workers > max_allowed:
|
|
30
30
|
raise OrionisTestValueError(
|
|
31
31
|
f"Invalid max_workers: Expected a positive integer between 1 and {max_allowed}, got '{max_workers}' ({type(max_workers).__name__})."
|
|
@@ -2,13 +2,16 @@ orionis/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
2
2
|
orionis/app.py,sha256=b69fOzj2J8Aw5g0IldWZXixUDeeTO9vcHc_Njses9HU,603
|
|
3
3
|
orionis/console/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
4
|
orionis/console/kernel.py,sha256=1CuBCLR6KItRt0_m50YQXirJUMX6lJf4Z4vvOjBqaUU,856
|
|
5
|
-
orionis/console/
|
|
6
|
-
orionis/console/
|
|
5
|
+
orionis/console/args/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
orionis/console/args/argument.py,sha256=ZbY8Gbxbk6pvORRL1evzXB9qGesepD0zdbMsbqfcFjw,14688
|
|
7
|
+
orionis/console/args/parser.py,sha256=WRaeyRjqnwXKBLn56sK2jubS_DAPbfVQ2rtfUGluA8A,101
|
|
8
|
+
orionis/console/args/enums/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
orionis/console/args/enums/actions.py,sha256=S3T-vWS6DJSGtANrq3od3-90iYAjPvJwaOZ2V02y34c,1222
|
|
7
10
|
orionis/console/base/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
11
|
orionis/console/base/command.py,sha256=2kKyTaEzI16Up-XCUeNeJmDWPLN-CweQm3EgrN9U8NQ,3027
|
|
9
12
|
orionis/console/base/contracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
13
|
orionis/console/base/contracts/command.py,sha256=s9yjma-s1URkVm0EbVvSkETAm-N8xX7OnZS43P8pvk8,1957
|
|
11
|
-
orionis/console/commands/version.py,sha256=
|
|
14
|
+
orionis/console/commands/version.py,sha256=kR8xzyc-Wisk7AXqg3Do7M9xTg_CxJgAtESPGrbRtpI,1673
|
|
12
15
|
orionis/console/contracts/kernel.py,sha256=mh4LlhEYHh3FuGZZQ0GBhD6ZLa5YQvaNj2r01IIHI5Y,826
|
|
13
16
|
orionis/console/core/reactor.py,sha256=lNfj-L4MKZhBn07l4H5L5dVW2xBRiq6-kyIuqnUNawQ,73
|
|
14
17
|
orionis/console/dumper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -173,10 +176,10 @@ orionis/foundation/providers/inspirational_provider.py,sha256=ZIsuEq2Sif7C1b1hYC
|
|
|
173
176
|
orionis/foundation/providers/logger_provider.py,sha256=PvwMxP5TKmn9DP8H8nJfyr16XgiJaGHyxPSMOpFgv84,1448
|
|
174
177
|
orionis/foundation/providers/path_resolver_provider.py,sha256=s44Mg68RsUNPlilQlXMBE7onVexa7kyDmVQmci1JL4g,1342
|
|
175
178
|
orionis/foundation/providers/progress_bar_provider.py,sha256=P__zpCyC29WCwErYGbh5dgcMRxw3XYmHzaUkzms9vPM,1345
|
|
176
|
-
orionis/foundation/providers/testing_provider.py,sha256=
|
|
179
|
+
orionis/foundation/providers/testing_provider.py,sha256=fSZfwKnScTxGlGrcEPReGIiOPs8XkoEaNNARN1wC6LU,2939
|
|
177
180
|
orionis/foundation/providers/workers_provider.py,sha256=YMRLdq_YQnR1unnoYvDpYQZbLli04f0CckuR6Q--wKg,1379
|
|
178
181
|
orionis/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
179
|
-
orionis/metadata/framework.py,sha256=
|
|
182
|
+
orionis/metadata/framework.py,sha256=Que9Q_spu-gld9CNZt90yTGnUPDQBWf87yrjBiveqPQ,4088
|
|
180
183
|
orionis/metadata/package.py,sha256=k7Yriyp5aUcR-iR8SK2ec_lf0_Cyc-C7JczgXa-I67w,16039
|
|
181
184
|
orionis/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
182
185
|
orionis/services/asynchrony/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -302,7 +305,7 @@ orionis/support/standard/exceptions/value.py,sha256=rsyWFQweImaJGTJa7Id7RhPlwWJ4
|
|
|
302
305
|
orionis/support/wrapper/__init__.py,sha256=jGoWoIGYuRYqMYQKlrX7Dpcbg-AGkHoB_aM2xhu73yc,62
|
|
303
306
|
orionis/support/wrapper/dot_dict.py,sha256=T8xWwwOhBZHNeXRwE_CxvOwG9UFxsLqNmOJjV2CNIrc,7284
|
|
304
307
|
orionis/test/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
305
|
-
orionis/test/kernel.py,sha256=
|
|
308
|
+
orionis/test/kernel.py,sha256=nJJDN2xusp9VZzezfocIvoenT2BheverjSovYCbRECg,3229
|
|
306
309
|
orionis/test/cases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
307
310
|
orionis/test/cases/asynchronous.py,sha256=3e1Y3qzIxVU7i7lbLFEVyJ89IA74JsB7famx71W-p2E,1974
|
|
308
311
|
orionis/test/cases/synchronous.py,sha256=S5jhuDEZ5I9wosrTFaCtowkD5r5HzJH6mKPOdEJcDJE,1734
|
|
@@ -315,7 +318,7 @@ orionis/test/contracts/render.py,sha256=wpDQzUtT0r8KFZ7zPcxWHXQ1EVNKxzA_rZ6ZKUcZ
|
|
|
315
318
|
orionis/test/contracts/test_result.py,sha256=SNXJ2UerkweYn7uCT0i0HmMGP0XBrL_9KJs-0ZvIYU4,4002
|
|
316
319
|
orionis/test/contracts/unit_test.py,sha256=PSnjEyM-QGQ3Pm0ZOqaa8QdPOtilGBVO4R87JYdVa-8,5386
|
|
317
320
|
orionis/test/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
318
|
-
orionis/test/core/unit_test.py,sha256=
|
|
321
|
+
orionis/test/core/unit_test.py,sha256=IIpPLM4pXZKCpKAZ-0PPatGuWjBXxgjKQxB8IJLB1zY,63310
|
|
319
322
|
orionis/test/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
320
323
|
orionis/test/entities/result.py,sha256=IMAd1AiwOf2z8krTDBFMpQe_1PG4YJ5Z0qpbr9xZwjg,4507
|
|
321
324
|
orionis/test/enums/__init__.py,sha256=M3imAgMvKFTKg55FbtVoY3zxj7QRY9AfaUWxiSZVvn4,66
|
|
@@ -346,10 +349,10 @@ orionis/test/validators/tags.py,sha256=Qv-p8XFyAjY7OI861s52eADGf3LqzOWYfKt4L1cpo
|
|
|
346
349
|
orionis/test/validators/throw_exception.py,sha256=PLtM94BArQf11VJhxfBHJSHARZSia-Q8ePixctU2JwQ,893
|
|
347
350
|
orionis/test/validators/verbosity.py,sha256=rADzM82cPcJ2_6crszpobJuwb5WihWNQf6i4M_yrCpw,1785
|
|
348
351
|
orionis/test/validators/web_report.py,sha256=n9BfzOZz6aEiNTypXcwuWbFRG0OdHNSmCNusHqc02R8,853
|
|
349
|
-
orionis/test/validators/workers.py,sha256=
|
|
352
|
+
orionis/test/validators/workers.py,sha256=rWcdRexINNEmGaO7mnc1MKUxkHKxrTsVuHgbnIfJYgc,1206
|
|
350
353
|
orionis/test/view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
351
354
|
orionis/test/view/render.py,sha256=f-zNhtKSg9R5Njqujbg2l2amAs2-mRVESneLIkWOZjU,4082
|
|
352
|
-
orionis-0.
|
|
355
|
+
orionis-0.444.0.dist-info/licenses/LICENCE,sha256=JhC-z_9mbpUrCfPjcl3DhDA8trNDMzb57cvRSam1avc,1463
|
|
353
356
|
tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
354
357
|
tests/container/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
355
358
|
tests/container/context/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -495,8 +498,8 @@ tests/testing/validators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZ
|
|
|
495
498
|
tests/testing/validators/test_testing_validators.py,sha256=WPo5GxTP6xE-Dw3X1vZoqOMpb6HhokjNSbgDsDRDvy4,16588
|
|
496
499
|
tests/testing/view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
497
500
|
tests/testing/view/test_render.py,sha256=tnnMBwS0iKUIbogLvu-7Rii50G6Koddp3XT4wgdFEYM,1050
|
|
498
|
-
orionis-0.
|
|
499
|
-
orionis-0.
|
|
500
|
-
orionis-0.
|
|
501
|
-
orionis-0.
|
|
502
|
-
orionis-0.
|
|
501
|
+
orionis-0.444.0.dist-info/METADATA,sha256=YgxccCDNizNHssu-14sVeL6dVMvkTMfvdfd3UcB1SeY,4772
|
|
502
|
+
orionis-0.444.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
503
|
+
orionis-0.444.0.dist-info/top_level.txt,sha256=2bdoHgyGZhOtLAXS6Om8OCTmL24dUMC_L1quMe_ETbk,14
|
|
504
|
+
orionis-0.444.0.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
|
|
505
|
+
orionis-0.444.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|