orionis 0.283.0__py3-none-any.whl → 0.285.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/foundation/config/testing/entities/testing.py +25 -0
- orionis/metadata/framework.py +1 -1
- orionis/services/asynchrony/{async_io.py → coroutines.py} +2 -1
- orionis/services/asynchrony/exceptions/__init__.py +0 -0
- orionis/services/asynchrony/exceptions/coroutine_exception.py +26 -0
- orionis/services/environment/dot_env.py +7 -7
- orionis/services/environment/env.py +56 -8
- orionis/services/environment/exceptions/__init__.py +0 -0
- orionis/services/environment/exceptions/value_exception.py +27 -0
- orionis/services/introspection/exceptions/__init__.py +0 -0
- orionis/services/introspection/exceptions/types.py +0 -0
- orionis/services/introspection/helpers/__init__.py +0 -0
- orionis/services/introspection/helpers/functions.py +285 -0
- orionis/services/introspection/reflection.py +216 -0
- orionis/services/parsers/exceptions/__init__.py +0 -0
- orionis/services/parsers/serializer.py +1 -1
- orionis/services/paths/exceptions/__init__.py +0 -0
- orionis/services/paths/exceptions/not_found_exceptions.py +28 -0
- orionis/services/paths/exceptions/path_value_exceptions.py +28 -0
- orionis/services/paths/resolver.py +6 -4
- orionis/services/standard/exceptions/__init__.py +0 -0
- orionis/services/standard/exceptions/path_value_exceptions.py +28 -0
- orionis/services/standard/std.py +4 -3
- orionis/test/entities/test_result.py +14 -1
- orionis/test/exceptions/test_persistence_error.py +34 -0
- orionis/test/exceptions/test_runtime_error.py +26 -0
- orionis/test/exceptions/test_value_error.py +26 -0
- orionis/test/logs/contracts/history.py +29 -56
- orionis/test/logs/history.py +309 -188
- orionis/test/output/contracts/dumper.py +24 -8
- orionis/test/output/dumper.py +52 -21
- orionis/test/suites/contracts/test_suite.py +27 -13
- orionis/test/suites/contracts/test_unit.py +101 -61
- orionis/test/suites/test_suite.py +45 -24
- orionis/test/suites/test_unit.py +559 -290
- orionis/unittesting.py +8 -0
- {orionis-0.283.0.dist-info → orionis-0.285.0.dist-info}/METADATA +1 -1
- {orionis-0.283.0.dist-info → orionis-0.285.0.dist-info}/RECORD +44 -26
- tests/services/asynchrony/test_async_io.py +3 -2
- /orionis/services/parsers/{exception.py → exceptions/exception_parser.py} +0 -0
- {orionis-0.283.0.dist-info → orionis-0.285.0.dist-info}/WHEEL +0 -0
- {orionis-0.283.0.dist-info → orionis-0.285.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.283.0.dist-info → orionis-0.285.0.dist-info}/top_level.txt +0 -0
- {orionis-0.283.0.dist-info → orionis-0.285.0.dist-info}/zip-safe +0 -0
@@ -0,0 +1,216 @@
|
|
1
|
+
import abc
|
2
|
+
from typing import Any, Type, TypeVar
|
3
|
+
from orionis._contracts.support.reflection import IReflection
|
4
|
+
from orionis.support.introspection.helpers.functions import HelpersReflection
|
5
|
+
from orionis.support.introspection.abstracts.reflect_abstract import ReflexionAbstract
|
6
|
+
from orionis.support.introspection.reflexion_concrete import ReflexionConcrete
|
7
|
+
from orionis.support.introspection.reflexion_concrete_with_abstract import ReflexionConcreteWithAbstract
|
8
|
+
from orionis.support.introspection.instances.reflection_instance import ReflectionInstance
|
9
|
+
from orionis.support.introspection.reflexion_instance_with_abstract import ReflexionInstanceWithAbstract
|
10
|
+
from orionis.support.introspection.reflexion_module import ReflexionModule
|
11
|
+
from orionis.support.introspection.reflexion_module_with_classname import ReflexionModuleWithClassName
|
12
|
+
|
13
|
+
T = TypeVar('T')
|
14
|
+
ABC = TypeVar('ABC', bound=abc.ABC)
|
15
|
+
|
16
|
+
class Reflection(IReflection):
|
17
|
+
"""A static class providing factory methods for creating reflection objects.
|
18
|
+
|
19
|
+
This class provides methods to create various types of reflection objects
|
20
|
+
that encapsulate different aspects of Python's reflection capabilities.
|
21
|
+
Each method validates its inputs before creating the appropriate reflection object.
|
22
|
+
|
23
|
+
Methods
|
24
|
+
-------
|
25
|
+
instance(instance: Any) -> ReflexionInstance
|
26
|
+
Creates a reflection object for a class instance
|
27
|
+
instanceWithAbstract(instance: Any, abstract: Type[ABC]) -> ReflexionInstanceWithAbstract
|
28
|
+
Creates a reflection object for a class instance with its abstract parent
|
29
|
+
abstract(abstract: Type[ABC]) -> ReflexionAbstract
|
30
|
+
Creates a reflection object for an abstract class
|
31
|
+
concrete(concrete: Type[T]) -> ReflexionConcrete
|
32
|
+
Creates a reflection object for a concrete class
|
33
|
+
concreteWithAbstract(concrete: Type[T], abstract: Type[ABC]) -> ReflexionConcreteWithAbstract
|
34
|
+
Creates a reflection object for a concrete class with its abstract parent
|
35
|
+
module(module: str) -> ReflexionModule
|
36
|
+
Creates a reflection object for a module
|
37
|
+
moduleWithClassName(module: str, class_name: str) -> ReflexionModuleWithClassName
|
38
|
+
Creates a reflection object for a module with a specific class name
|
39
|
+
"""
|
40
|
+
|
41
|
+
@staticmethod
|
42
|
+
def instance(instance: Any) -> 'ReflectionInstance':
|
43
|
+
"""Create a reflection object for a class instance.
|
44
|
+
|
45
|
+
Parameters
|
46
|
+
----------
|
47
|
+
instance : Any
|
48
|
+
The instance to reflect upon
|
49
|
+
|
50
|
+
Returns
|
51
|
+
-------
|
52
|
+
ReflectionInstance
|
53
|
+
A reflection object encapsulating the instance
|
54
|
+
|
55
|
+
Raises
|
56
|
+
------
|
57
|
+
TypeError
|
58
|
+
If the input is not an object instance
|
59
|
+
ValueError
|
60
|
+
If the instance is from builtins, abc, or __main__
|
61
|
+
"""
|
62
|
+
HelpersReflection.ensureUserDefinedClassInstance(instance)
|
63
|
+
return ReflectionInstance(instance)
|
64
|
+
|
65
|
+
@staticmethod
|
66
|
+
def instanceWithAbstract(instance: Any, abstract: Type[ABC]) -> 'ReflexionInstanceWithAbstract':
|
67
|
+
"""Create a reflection object for a class instance with its abstract parent.
|
68
|
+
|
69
|
+
Parameters
|
70
|
+
----------
|
71
|
+
instance : Any
|
72
|
+
The instance to reflect upon
|
73
|
+
abstract : Type[ABC]
|
74
|
+
The abstract parent class
|
75
|
+
|
76
|
+
Returns
|
77
|
+
-------
|
78
|
+
ReflexionInstanceWithAbstract
|
79
|
+
A reflection object encapsulating the instance and its abstract parent
|
80
|
+
|
81
|
+
Raises
|
82
|
+
------
|
83
|
+
TypeError
|
84
|
+
If the instance is not an object or abstract is not a class
|
85
|
+
ValueError
|
86
|
+
If the instance is invalid or abstract is not actually abstract
|
87
|
+
"""
|
88
|
+
HelpersReflection.ensureUserDefinedClassInstance(instance)
|
89
|
+
HelpersReflection.ensureAbstractClass(abstract)
|
90
|
+
return ReflexionInstanceWithAbstract(instance, abstract)
|
91
|
+
|
92
|
+
@staticmethod
|
93
|
+
def abstract(abstract: Type[ABC]) -> 'ReflexionAbstract':
|
94
|
+
"""Create a reflection object for an abstract class.
|
95
|
+
|
96
|
+
Parameters
|
97
|
+
----------
|
98
|
+
abstract : Type[ABC]
|
99
|
+
The abstract class to reflect upon
|
100
|
+
|
101
|
+
Returns
|
102
|
+
-------
|
103
|
+
ReflexionAbstract
|
104
|
+
A reflection object encapsulating the abstract class
|
105
|
+
|
106
|
+
Raises
|
107
|
+
------
|
108
|
+
TypeError
|
109
|
+
If the input is not a class
|
110
|
+
ValueError
|
111
|
+
If the class is not abstract
|
112
|
+
"""
|
113
|
+
HelpersReflection.ensureAbstractClass(abstract)
|
114
|
+
return ReflexionAbstract(abstract)
|
115
|
+
|
116
|
+
@staticmethod
|
117
|
+
def concrete(concrete: Type[T]) -> 'ReflexionConcrete':
|
118
|
+
"""Create a reflection object for a concrete class.
|
119
|
+
|
120
|
+
Parameters
|
121
|
+
----------
|
122
|
+
concrete : Type[T]
|
123
|
+
The concrete class to reflect upon
|
124
|
+
|
125
|
+
Returns
|
126
|
+
-------
|
127
|
+
ReflexionConcrete
|
128
|
+
A reflection object encapsulating the concrete class
|
129
|
+
|
130
|
+
Raises
|
131
|
+
------
|
132
|
+
TypeError
|
133
|
+
If the input is not a class
|
134
|
+
ValueError
|
135
|
+
If the class is abstract or cannot be instantiated
|
136
|
+
"""
|
137
|
+
HelpersReflection.ensureInstantiableClass(concrete)
|
138
|
+
return ReflexionConcrete(concrete)
|
139
|
+
|
140
|
+
@staticmethod
|
141
|
+
def concreteWithAbstract(concrete: Type[T], abstract: Type[ABC]) -> 'ReflexionConcreteWithAbstract':
|
142
|
+
"""Create a reflection object for a concrete class with its abstract parent.
|
143
|
+
|
144
|
+
Parameters
|
145
|
+
----------
|
146
|
+
concrete : Type[T]
|
147
|
+
The concrete class to reflect upon
|
148
|
+
abstract : Type[ABC]
|
149
|
+
The abstract parent class
|
150
|
+
|
151
|
+
Returns
|
152
|
+
-------
|
153
|
+
ReflexionConcreteWithAbstract
|
154
|
+
A reflection object encapsulating the concrete class and its abstract parent
|
155
|
+
|
156
|
+
Raises
|
157
|
+
------
|
158
|
+
TypeError
|
159
|
+
If either input is not a class
|
160
|
+
ValueError
|
161
|
+
If concrete is not instantiable or abstract is not actually abstract
|
162
|
+
"""
|
163
|
+
HelpersReflection.ensureInstantiableClass(concrete)
|
164
|
+
HelpersReflection.ensureAbstractClass(abstract)
|
165
|
+
return ReflexionConcreteWithAbstract(concrete, abstract)
|
166
|
+
|
167
|
+
@staticmethod
|
168
|
+
def module(module: str) -> 'ReflexionModule':
|
169
|
+
"""Create a reflection object for a module.
|
170
|
+
|
171
|
+
Parameters
|
172
|
+
----------
|
173
|
+
module : str
|
174
|
+
The module name to reflect upon
|
175
|
+
|
176
|
+
Returns
|
177
|
+
-------
|
178
|
+
ReflexionModule
|
179
|
+
A reflection object encapsulating the module
|
180
|
+
|
181
|
+
Raises
|
182
|
+
------
|
183
|
+
TypeError
|
184
|
+
If the input is not a string
|
185
|
+
ValueError
|
186
|
+
If the module cannot be imported
|
187
|
+
"""
|
188
|
+
HelpersReflection.ensureValidModule(module)
|
189
|
+
return ReflexionModule(module)
|
190
|
+
|
191
|
+
@staticmethod
|
192
|
+
def moduleWithClassName(module: str, class_name: str) -> 'ReflexionModuleWithClassName':
|
193
|
+
"""Create a reflection object for a module with a specific class name.
|
194
|
+
|
195
|
+
Parameters
|
196
|
+
----------
|
197
|
+
module : str
|
198
|
+
The module name to reflect upon
|
199
|
+
class_name : str
|
200
|
+
The class name to look for in the module
|
201
|
+
|
202
|
+
Returns
|
203
|
+
-------
|
204
|
+
ReflexionModuleWithClassName
|
205
|
+
A reflection object encapsulating the module and class name
|
206
|
+
|
207
|
+
Raises
|
208
|
+
------
|
209
|
+
TypeError
|
210
|
+
If either input is not a string
|
211
|
+
ValueError
|
212
|
+
If the module cannot be imported or the class doesn't exist in it
|
213
|
+
"""
|
214
|
+
HelpersReflection.ensureValidModule(module)
|
215
|
+
HelpersReflection.ensureValidClassName(class_name)
|
216
|
+
return ReflexionModuleWithClassName(module, class_name)
|
File without changes
|
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class OrionisFileNotFoundException(Exception):
|
2
|
+
"""
|
3
|
+
Exception raised when a file is not found in the Orionis framework.
|
4
|
+
|
5
|
+
Args:
|
6
|
+
msg (str): A detailed message describing the missing file.
|
7
|
+
|
8
|
+
Example:
|
9
|
+
raise OrionisFileNotFoundException("File 'config.yaml' not found.")
|
10
|
+
"""
|
11
|
+
|
12
|
+
def __init__(self, msg: str):
|
13
|
+
"""
|
14
|
+
Initializes the exception with a custom error message.
|
15
|
+
|
16
|
+
Args:
|
17
|
+
msg (str): The error message describing the exception.
|
18
|
+
"""
|
19
|
+
super().__init__(msg)
|
20
|
+
|
21
|
+
def __str__(self) -> str:
|
22
|
+
"""
|
23
|
+
Return a string representation of the exception, including the class name and the first argument.
|
24
|
+
|
25
|
+
Returns:
|
26
|
+
str: A formatted string with the exception class name and the first argument.
|
27
|
+
"""
|
28
|
+
return f"{self.__class__.__name__}: {self.args[0]}"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class OrionisPathValueException(Exception):
|
2
|
+
"""
|
3
|
+
Exception raised when a file is not found in the Orionis framework.
|
4
|
+
|
5
|
+
Args:
|
6
|
+
msg (str): A detailed message describing the missing file.
|
7
|
+
|
8
|
+
Example:
|
9
|
+
raise OrionisFileNotFoundException("File 'config.yaml' not found.")
|
10
|
+
"""
|
11
|
+
|
12
|
+
def __init__(self, msg: str):
|
13
|
+
"""
|
14
|
+
Initializes the exception with a custom error message.
|
15
|
+
|
16
|
+
Args:
|
17
|
+
msg (str): The error message describing the exception.
|
18
|
+
"""
|
19
|
+
super().__init__(msg)
|
20
|
+
|
21
|
+
def __str__(self) -> str:
|
22
|
+
"""
|
23
|
+
Return a string representation of the exception, including the class name and the first argument.
|
24
|
+
|
25
|
+
Returns:
|
26
|
+
str: A formatted string with the exception class name and the first argument.
|
27
|
+
"""
|
28
|
+
return f"{self.__class__.__name__}: {self.args[0]}"
|
@@ -1,6 +1,8 @@
|
|
1
1
|
import os
|
2
2
|
from pathlib import Path
|
3
3
|
from orionis.services.paths.contracts.resolver import IResolver
|
4
|
+
from orionis.services.paths.exceptions.not_found_exceptions import OrionisFileNotFoundException
|
5
|
+
from orionis.services.paths.exceptions.path_value_exceptions import OrionisPathValueException
|
4
6
|
|
5
7
|
class Resolver(IResolver):
|
6
8
|
"""
|
@@ -38,9 +40,9 @@ class Resolver(IResolver):
|
|
38
40
|
|
39
41
|
Raises
|
40
42
|
------
|
41
|
-
|
43
|
+
OrionisFileNotFoundException
|
42
44
|
If the resolved path does not exist.
|
43
|
-
|
45
|
+
OrionisPathValueException
|
44
46
|
If the resolved path is neither a valid directory nor a file.
|
45
47
|
"""
|
46
48
|
# Combine the base path with the relative path and resolve it
|
@@ -48,11 +50,11 @@ class Resolver(IResolver):
|
|
48
50
|
|
49
51
|
# Validate that the path exists
|
50
52
|
if not resolved_path.exists():
|
51
|
-
raise
|
53
|
+
raise OrionisFileNotFoundException(f"The requested path does not exist: {resolved_path}")
|
52
54
|
|
53
55
|
# Validate that the path is either a directory or a file
|
54
56
|
if not (resolved_path.is_dir() or resolved_path.is_file()):
|
55
|
-
raise
|
57
|
+
raise OrionisPathValueException(f"The requested path is neither a valid directory nor a file: {resolved_path}")
|
56
58
|
|
57
59
|
# Store the resolved path in the instance variable
|
58
60
|
self.resolved_path = resolved_path
|
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
class OrionisStdValueException(Exception):
|
2
|
+
"""
|
3
|
+
Exception raised for standard value errors in the Orionis framework.
|
4
|
+
|
5
|
+
Args:
|
6
|
+
msg (str): A detailed message describing the value error.
|
7
|
+
|
8
|
+
Example:
|
9
|
+
raise OrionisStdValueException("Invalid value for parameter 'timeout'.")
|
10
|
+
"""
|
11
|
+
|
12
|
+
def __init__(self, msg: str):
|
13
|
+
"""
|
14
|
+
Initializes the exception with a custom error message.
|
15
|
+
|
16
|
+
Args:
|
17
|
+
msg (str): The error message describing the exception.
|
18
|
+
"""
|
19
|
+
super().__init__(msg)
|
20
|
+
|
21
|
+
def __str__(self) -> str:
|
22
|
+
"""
|
23
|
+
Return a string representation of the exception, including the class name and the first argument.
|
24
|
+
|
25
|
+
Returns:
|
26
|
+
str: A formatted string with the exception class name and the first argument.
|
27
|
+
"""
|
28
|
+
return f"{self.__class__.__name__}: {self.args[0]}"
|
orionis/services/standard/std.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
from orionis.services.standard.contracts.std import IStdClass
|
2
|
+
from orionis.services.standard.exceptions.path_value_exceptions import OrionisStdValueException
|
2
3
|
|
3
4
|
class StdClass(IStdClass):
|
4
5
|
"""
|
@@ -81,14 +82,14 @@ class StdClass(IStdClass):
|
|
81
82
|
|
82
83
|
Raises
|
83
84
|
------
|
84
|
-
|
85
|
+
OrionisStdValueException
|
85
86
|
If an attribute name is invalid or conflicts with existing methods.
|
86
87
|
"""
|
87
88
|
for key, value in kwargs.items():
|
88
89
|
if key.startswith('__') and key.endswith('__'):
|
89
|
-
raise
|
90
|
+
raise OrionisStdValueException(f"Cannot set attribute with reserved name: {key}")
|
90
91
|
if hasattr(self.__class__, key):
|
91
|
-
raise
|
92
|
+
raise OrionisStdValueException(f"Cannot set attribute '{key}' as it conflicts with a class method")
|
92
93
|
setattr(self, key, value)
|
93
94
|
|
94
95
|
def remove(self, *attributes):
|
@@ -5,9 +5,22 @@ from orionis.test.enums.test_status import TestStatus
|
|
5
5
|
@dataclass(frozen=True, kw_only=True)
|
6
6
|
class TestResult:
|
7
7
|
"""
|
8
|
-
Represents the result of a test execution.
|
8
|
+
Represents the result of a test execution, including status, timing, and error details.
|
9
|
+
Attributes:
|
10
|
+
id (Any): Unique identifier for the test result.
|
11
|
+
name (str): Name of the test.
|
12
|
+
status (TestStatus): Status of the test execution (e.g., passed, failed).
|
13
|
+
execution_time (float): Time taken to execute the test, in seconds.
|
14
|
+
error_message (Optional[str]): Error message if the test failed, otherwise None.
|
15
|
+
traceback (Optional[str]): Traceback information if an error occurred, otherwise None.
|
16
|
+
class_name (Optional[str]): Name of the class containing the test, if applicable.
|
17
|
+
method (Optional[str]): Name of the method representing the test, if applicable.
|
18
|
+
module (Optional[str]): Name of the module containing the test, if applicable.
|
19
|
+
file_path (Optional[str]): Path to the file containing the test, if applicable.
|
20
|
+
doc_string (Optional[str]): Docstring of the test, if applicable.
|
9
21
|
"""
|
10
22
|
|
23
|
+
|
11
24
|
id: Any = field(
|
12
25
|
metadata={
|
13
26
|
"description": "Unique identifier for the test result."
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class OrionisTestPersistenceError(Exception):
|
2
|
+
"""
|
3
|
+
Custom exception for persistence errors in tests within the Orionis framework.
|
4
|
+
|
5
|
+
This exception is used to indicate issues related to data persistence during test execution,
|
6
|
+
providing a descriptive message to help identify and resolve the error.
|
7
|
+
|
8
|
+
Args:
|
9
|
+
msg (str): A descriptive message explaining the cause of the persistence error.
|
10
|
+
|
11
|
+
Example:
|
12
|
+
raise OrionisTestPersistenceError("Failed to save test state to the database.")
|
13
|
+
"""
|
14
|
+
|
15
|
+
def __init__(self, msg: str):
|
16
|
+
"""
|
17
|
+
Initializes the OrionisTestConfigException with a specific error message.
|
18
|
+
|
19
|
+
Args:
|
20
|
+
msg (str): A descriptive error message explaining the cause of the exception.
|
21
|
+
"""
|
22
|
+
super().__init__(msg)
|
23
|
+
|
24
|
+
def __str__(self) -> str:
|
25
|
+
"""
|
26
|
+
Returns a formatted string representation of the exception.
|
27
|
+
|
28
|
+
The string includes the exception name and the error message, providing
|
29
|
+
a clear and concise description of the issue.
|
30
|
+
|
31
|
+
Returns:
|
32
|
+
str: A formatted string describing the exception.
|
33
|
+
"""
|
34
|
+
return f"{self.__class__.__name__}: {self.args[0]}"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class OrionisTestRuntimeError(Exception):
|
2
|
+
"""
|
3
|
+
Exception raised for errors that occur during the runtime of Orionis tests.
|
4
|
+
This exception is intended to provide a clear and descriptive error message
|
5
|
+
when a runtime error is encountered in the Orionis testing framework.
|
6
|
+
Attributes:
|
7
|
+
Example:
|
8
|
+
raise OrionisTestRuntimeError("An unexpected runtime error occurred during testing.")
|
9
|
+
"""
|
10
|
+
|
11
|
+
def __init__(self, msg: str):
|
12
|
+
"""
|
13
|
+
Initializes the exception with a given error message.
|
14
|
+
Args:
|
15
|
+
msg (str): The error message describing the runtime error.
|
16
|
+
"""
|
17
|
+
super().__init__(msg)
|
18
|
+
|
19
|
+
def __str__(self) -> str:
|
20
|
+
"""
|
21
|
+
Return a string representation of the exception, including the class name and the first argument.
|
22
|
+
|
23
|
+
Returns:
|
24
|
+
str: A string in the format '<ClassName>: <first argument>'.
|
25
|
+
"""
|
26
|
+
return f"{self.__class__.__name__}: {self.args[0]}"
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class OrionisTestValueError(Exception):
|
2
|
+
"""
|
3
|
+
Custom exception class for handling value errors in the Orionis test framework.
|
4
|
+
This exception should be raised when a value-related error occurs during testing.
|
5
|
+
It provides a formatted string representation that includes the class name and the error message.
|
6
|
+
Example:
|
7
|
+
raise OrionisTestValueError("Invalid value provided.")
|
8
|
+
"""
|
9
|
+
|
10
|
+
def __init__(self, msg: str):
|
11
|
+
"""
|
12
|
+
Initializes the exception with a custom error message.
|
13
|
+
|
14
|
+
Args:
|
15
|
+
msg (str): The error message describing the exception.
|
16
|
+
"""
|
17
|
+
super().__init__(msg)
|
18
|
+
|
19
|
+
def __str__(self) -> str:
|
20
|
+
"""
|
21
|
+
Return a string representation of the exception, including the class name and the first argument.
|
22
|
+
|
23
|
+
Returns:
|
24
|
+
str: A formatted string in the form 'ClassName: message'.
|
25
|
+
"""
|
26
|
+
return f"{self.__class__.__name__}: {self.args[0]}"
|
@@ -1,81 +1,54 @@
|
|
1
1
|
from abc import ABC, abstractmethod
|
2
|
-
from typing import Dict, List, Tuple
|
2
|
+
from typing import Dict, List, Optional, Tuple
|
3
3
|
|
4
4
|
class ITestHistory(ABC):
|
5
5
|
|
6
6
|
@abstractmethod
|
7
|
-
def
|
7
|
+
def create(self, report: Dict) -> bool:
|
8
8
|
"""
|
9
|
-
Create
|
10
|
-
|
11
|
-
The table includes fields for the full JSON report and individual
|
12
|
-
statistics for querying and filtering.
|
13
|
-
|
14
|
-
Raises
|
15
|
-
------
|
16
|
-
RuntimeError
|
17
|
-
If table creation fails due to a database error.
|
18
|
-
"""
|
19
|
-
pass
|
20
|
-
|
21
|
-
@abstractmethod
|
22
|
-
def insertReport(self, report: Dict) -> None:
|
23
|
-
"""
|
24
|
-
Insert a test report into the database.
|
9
|
+
Create a new test report in the history database.
|
25
10
|
|
26
11
|
Parameters
|
27
12
|
----------
|
28
|
-
report :
|
29
|
-
|
30
|
-
|
31
|
-
Required keys:
|
32
|
-
- total_tests : int
|
33
|
-
- passed : int
|
34
|
-
- failed : int
|
35
|
-
- errors : int
|
36
|
-
- skipped : int
|
37
|
-
- total_time : float
|
38
|
-
- success_rate : float
|
39
|
-
- timestamp : str (ISO format)
|
13
|
+
report : Dict
|
14
|
+
A dictionary containing the test report data.
|
40
15
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
RuntimeError
|
46
|
-
If insertion into the database fails.
|
16
|
+
Returns
|
17
|
+
-------
|
18
|
+
bool
|
19
|
+
True if the report was successfully created, False otherwise.
|
47
20
|
"""
|
48
21
|
pass
|
49
22
|
|
50
|
-
def
|
23
|
+
def reset(self) -> bool:
|
51
24
|
"""
|
52
|
-
|
25
|
+
Reset the history database by dropping the existing table.
|
53
26
|
|
54
27
|
Returns
|
55
28
|
-------
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
Raises
|
60
|
-
------
|
61
|
-
RuntimeError
|
62
|
-
If retrieval fails due to a database error.
|
29
|
+
bool
|
30
|
+
True if the database was successfully reset, False otherwise.
|
63
31
|
"""
|
64
32
|
pass
|
65
33
|
|
66
|
-
def
|
34
|
+
def get(
|
35
|
+
self,
|
36
|
+
first: Optional[int] = None,
|
37
|
+
last: Optional[int] = None
|
38
|
+
) -> List[Tuple]:
|
67
39
|
"""
|
68
|
-
|
40
|
+
Retrieve test reports from the history database.
|
69
41
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
42
|
+
Parameters
|
43
|
+
----------
|
44
|
+
first : Optional[int], default=None
|
45
|
+
The number of earliest reports to retrieve, ordered ascending by ID.
|
46
|
+
last : Optional[int], default=None
|
47
|
+
The number of latest reports to retrieve, ordered descending by ID.
|
76
48
|
|
77
|
-
|
78
|
-
|
79
|
-
|
49
|
+
Returns
|
50
|
+
-------
|
51
|
+
List[Tuple]
|
52
|
+
A list of tuples representing the retrieved reports.
|
80
53
|
"""
|
81
54
|
pass
|