orionis 0.405.0__py3-none-any.whl → 0.406.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.
Files changed (154) hide show
  1. orionis/console/base/command.py +57 -50
  2. orionis/console/base/contracts/command.py +68 -0
  3. orionis/console/dynamic/contracts/progress_bar.py +3 -3
  4. orionis/console/dynamic/progress_bar.py +8 -8
  5. orionis/console/output/console.py +8 -2
  6. orionis/console/output/contracts/console.py +1 -1
  7. orionis/container/container.py +2 -2
  8. orionis/container/context/scope.py +4 -1
  9. orionis/container/contracts/service_provider.py +2 -2
  10. orionis/container/entities/binding.py +31 -44
  11. orionis/container/enums/lifetimes.py +22 -1
  12. orionis/container/facades/facade.py +1 -2
  13. orionis/container/providers/service_provider.py +2 -2
  14. orionis/foundation/application.py +542 -248
  15. orionis/foundation/config/app/entities/app.py +107 -90
  16. orionis/foundation/config/auth/entities/auth.py +4 -33
  17. orionis/foundation/config/cache/entities/cache.py +18 -41
  18. orionis/foundation/config/cache/entities/file.py +8 -35
  19. orionis/foundation/config/cache/entities/stores.py +17 -38
  20. orionis/foundation/config/cors/entities/cors.py +41 -54
  21. orionis/foundation/config/database/entities/connections.py +40 -56
  22. orionis/foundation/config/database/entities/database.py +11 -38
  23. orionis/foundation/config/database/entities/mysql.py +48 -76
  24. orionis/foundation/config/database/entities/oracle.py +30 -57
  25. orionis/foundation/config/database/entities/pgsql.py +45 -61
  26. orionis/foundation/config/database/entities/sqlite.py +26 -53
  27. orionis/foundation/config/filesystems/entitites/aws.py +28 -49
  28. orionis/foundation/config/filesystems/entitites/disks.py +27 -47
  29. orionis/foundation/config/filesystems/entitites/filesystems.py +15 -37
  30. orionis/foundation/config/filesystems/entitites/local.py +9 -35
  31. orionis/foundation/config/filesystems/entitites/public.py +14 -41
  32. orionis/foundation/config/logging/entities/channels.py +56 -86
  33. orionis/foundation/config/logging/entities/chunked.py +9 -9
  34. orionis/foundation/config/logging/entities/daily.py +8 -8
  35. orionis/foundation/config/logging/entities/hourly.py +6 -6
  36. orionis/foundation/config/logging/entities/logging.py +12 -18
  37. orionis/foundation/config/logging/entities/monthly.py +7 -7
  38. orionis/foundation/config/logging/entities/stack.py +5 -5
  39. orionis/foundation/config/logging/entities/weekly.py +6 -6
  40. orionis/foundation/config/mail/entities/file.py +9 -36
  41. orionis/foundation/config/mail/entities/mail.py +22 -40
  42. orionis/foundation/config/mail/entities/mailers.py +29 -44
  43. orionis/foundation/config/mail/entities/smtp.py +47 -48
  44. orionis/foundation/config/queue/entities/brokers.py +19 -41
  45. orionis/foundation/config/queue/entities/database.py +24 -46
  46. orionis/foundation/config/queue/entities/queue.py +28 -40
  47. orionis/foundation/config/roots/paths.py +272 -468
  48. orionis/foundation/config/session/entities/session.py +23 -53
  49. orionis/foundation/config/startup.py +165 -135
  50. orionis/foundation/config/testing/entities/testing.py +137 -122
  51. orionis/foundation/config/testing/enums/__init__.py +6 -2
  52. orionis/foundation/config/testing/enums/drivers.py +16 -0
  53. orionis/foundation/config/testing/enums/verbosity.py +18 -0
  54. orionis/foundation/contracts/application.py +152 -362
  55. orionis/foundation/providers/console_provider.py +24 -2
  56. orionis/foundation/providers/dumper_provider.py +24 -2
  57. orionis/foundation/providers/logger_provider.py +24 -2
  58. orionis/foundation/providers/path_resolver_provider.py +25 -2
  59. orionis/foundation/providers/progress_bar_provider.py +24 -2
  60. orionis/foundation/providers/testing_provider.py +39 -0
  61. orionis/foundation/providers/workers_provider.py +24 -2
  62. orionis/metadata/framework.py +1 -1
  63. orionis/services/environment/helpers/functions.py +1 -2
  64. orionis/services/environment/key/__init__.py +0 -0
  65. orionis/services/environment/key/key_generator.py +37 -0
  66. orionis/support/entities/__init__.py +0 -0
  67. orionis/support/entities/base.py +104 -0
  68. orionis/support/facades/testing.py +15 -0
  69. orionis/support/facades/workers.py +1 -1
  70. orionis/test/cases/asynchronous.py +0 -11
  71. orionis/test/cases/synchronous.py +0 -9
  72. orionis/test/contracts/dumper.py +11 -4
  73. orionis/test/contracts/kernel.py +5 -110
  74. orionis/test/contracts/logs.py +27 -65
  75. orionis/test/contracts/printer.py +16 -128
  76. orionis/test/contracts/test_result.py +100 -0
  77. orionis/test/contracts/unit_test.py +87 -150
  78. orionis/test/core/unit_test.py +608 -554
  79. orionis/test/entities/result.py +22 -2
  80. orionis/test/enums/__init__.py +0 -2
  81. orionis/test/enums/status.py +14 -9
  82. orionis/test/exceptions/config.py +9 -1
  83. orionis/test/exceptions/failure.py +34 -11
  84. orionis/test/exceptions/persistence.py +10 -2
  85. orionis/test/exceptions/runtime.py +9 -1
  86. orionis/test/exceptions/value.py +13 -1
  87. orionis/test/kernel.py +87 -289
  88. orionis/test/output/dumper.py +82 -18
  89. orionis/test/output/printer.py +399 -156
  90. orionis/test/records/logs.py +203 -82
  91. orionis/test/validators/__init__.py +33 -0
  92. orionis/test/validators/base_path.py +45 -0
  93. orionis/test/validators/execution_mode.py +45 -0
  94. orionis/test/validators/fail_fast.py +37 -0
  95. orionis/test/validators/folder_path.py +34 -0
  96. orionis/test/validators/module_name.py +31 -0
  97. orionis/test/validators/name_pattern.py +40 -0
  98. orionis/test/validators/pattern.py +36 -0
  99. orionis/test/validators/persistent.py +42 -0
  100. orionis/test/validators/persistent_driver.py +43 -0
  101. orionis/test/validators/print_result.py +37 -0
  102. orionis/test/validators/tags.py +37 -0
  103. orionis/test/validators/throw_exception.py +39 -0
  104. orionis/test/validators/verbosity.py +37 -0
  105. orionis/test/validators/web_report.py +35 -0
  106. orionis/test/validators/workers.py +31 -0
  107. orionis/test/view/render.py +48 -54
  108. {orionis-0.405.0.dist-info → orionis-0.406.0.dist-info}/METADATA +1 -1
  109. {orionis-0.405.0.dist-info → orionis-0.406.0.dist-info}/RECORD +149 -98
  110. tests/container/__init__.py +0 -0
  111. tests/container/context/__init__.py +0 -0
  112. tests/container/context/test_manager.py +27 -0
  113. tests/container/context/test_scope.py +23 -0
  114. tests/container/entities/__init__.py +0 -0
  115. tests/container/entities/test_binding.py +133 -0
  116. tests/container/enums/__init__.py +0 -0
  117. tests/container/enums/test_lifetimes.py +63 -0
  118. tests/container/facades/__init__.py +0 -0
  119. tests/container/facades/test_facade.py +61 -0
  120. tests/container/mocks/__init__.py +0 -0
  121. tests/container/mocks/mock_complex_classes.py +482 -0
  122. tests/container/mocks/mock_simple_classes.py +32 -0
  123. tests/container/providers/__init__.py +0 -0
  124. tests/container/providers/test_providers.py +48 -0
  125. tests/container/resolver/__init__.py +0 -0
  126. tests/container/resolver/test_resolver.py +55 -0
  127. tests/container/test_container.py +254 -0
  128. tests/container/test_singleton.py +98 -0
  129. tests/container/test_thread_safety.py +217 -0
  130. tests/container/validators/__init__.py +0 -0
  131. tests/container/validators/test_implements.py +140 -0
  132. tests/container/validators/test_is_abstract_class.py +99 -0
  133. tests/container/validators/test_is_callable.py +73 -0
  134. tests/container/validators/test_is_concrete_class.py +97 -0
  135. tests/container/validators/test_is_instance.py +105 -0
  136. tests/container/validators/test_is_not_subclass.py +117 -0
  137. tests/container/validators/test_is_subclass.py +115 -0
  138. tests/container/validators/test_is_valid_alias.py +113 -0
  139. tests/container/validators/test_lifetime.py +75 -0
  140. tests/foundation/config/testing/test_foundation_config_testing.py +1 -1
  141. tests/metadata/test_metadata_framework.py +18 -18
  142. tests/testing/test_testing_result.py +117 -117
  143. tests/testing/test_testing_unit.py +209 -209
  144. orionis/foundation/config/base.py +0 -112
  145. orionis/test/arguments/parser.py +0 -187
  146. orionis/test/contracts/parser.py +0 -43
  147. orionis/test/entities/arguments.py +0 -38
  148. orionis/test/enums/execution_mode.py +0 -16
  149. /orionis/{test/arguments → console/base/contracts}/__init__.py +0 -0
  150. /orionis/foundation/config/testing/enums/{test_mode.py → mode.py} +0 -0
  151. {orionis-0.405.0.dist-info → orionis-0.406.0.dist-info}/WHEEL +0 -0
  152. {orionis-0.405.0.dist-info → orionis-0.406.0.dist-info}/licenses/LICENCE +0 -0
  153. {orionis-0.405.0.dist-info → orionis-0.406.0.dist-info}/top_level.txt +0 -0
  154. {orionis-0.405.0.dist-info → orionis-0.406.0.dist-info}/zip-safe +0 -0
@@ -1,179 +1,193 @@
1
- from dataclasses import asdict, dataclass, field, fields
1
+ from dataclasses import dataclass, field
2
2
  from typing import List
3
+ from orionis.support.entities.base import BaseEntity
4
+ from orionis.foundation.config.testing.enums import ExecutionMode, PersistentDrivers, VerbosityMode
3
5
  from orionis.foundation.exceptions import OrionisIntegrityException
4
6
  from orionis.services.system.workers import Workers
5
- from orionis.test.enums.execution_mode import ExecutionMode
6
7
 
7
8
  @dataclass(unsafe_hash=True, kw_only=True)
8
- class Testing:
9
+ class Testing(BaseEntity):
9
10
  """
10
- Testing is a dataclass that holds configuration options for running tests.
11
-
12
- Attributes:
13
- verbosity (int): The verbosity level of the test output. Default is 2.
14
- - 0: Silent
15
- - 1: Minimal output
16
- - 2: Detailed output (default)
17
- execution_mode (ExecutionMode): The mode of test execution. Default is ExecutionMode.SEQUENTIAL.
18
- - ExecutionMode.SEQUENTIAL: Tests are executed one after another.
19
- - ExecutionMode.PARALLEL: Tests are executed in parallel.
20
- max_workers (int): The maximum number of worker threads/processes to use when running tests in parallel. Default is 4.
21
- fail_fast (bool): Whether to stop execution after the first test failure. Default is False.
22
- print_result (bool): Whether to print the test results to the console. Default is True.
23
- throw_exception (bool): Whether to throw an exception if a test fails. Default is False.
24
- base_path (str): The base directory where tests are located. Default is 'tests'.
25
- folder_path (str): The folder path pattern to search for tests. Default is '*'.
26
- pattern (str): The filename pattern to identify test files. Default is 'test_*.py'.
27
- test_name_pattern (str | None): A pattern to match specific test names. Default is None.
28
- tags (List[str] | None): A list of tags to filter tests. Default is None.
11
+ Configuration dataclass for test execution options.
12
+
13
+ Parameters
14
+ ----------
15
+ verbosity : int or VerbosityMode, optional
16
+ Verbosity level for test output. 0 = silent, 1 = minimal, 2 = detailed (default: 2).
17
+ execution_mode : str or ExecutionMode, optional
18
+ Mode of test execution. 'SEQUENTIAL' runs tests one after another, 'PARALLEL' runs tests in parallel (default: 'SEQUENTIAL').
19
+ max_workers : int, optional
20
+ Maximum number of worker threads/processes for parallel execution (default: calculated by Workers).
21
+ fail_fast : bool, optional
22
+ If True, stop execution after the first test failure (default: False).
23
+ print_result : bool, optional
24
+ If True, print test results to the console (default: True).
25
+ throw_exception : bool, optional
26
+ If True, raise an exception on test failure (default: False).
27
+ base_path : str, optional
28
+ Base directory where tests are located (default: 'tests').
29
+ folder_path : str or list of str, optional
30
+ Folder path pattern(s) to search for tests (default: '*').
31
+ pattern : str, optional
32
+ Filename pattern to identify test files (default: 'test_*.py').
33
+ test_name_pattern : str or None, optional
34
+ Pattern to match specific test names (default: None).
35
+ tags : list of str or None, optional
36
+ List of tags to filter tests (default: empty list).
37
+ persistent : bool, optional
38
+ If True, keep test results persistent (default: False).
39
+ persistent_driver : str or PersistentDrivers, optional
40
+ Driver to use for persisting test results. Supported: 'sqlite', 'json' (default: 'json').
41
+ web_report : bool, optional
42
+ If True, generate a web report for test results (default: False).
43
+
44
+ Notes
45
+ -----
46
+ This class validates all configuration options on initialization and raises an exception if any value is invalid.
29
47
  """
30
48
 
31
- verbosity: int = field(
32
- default=2,
33
- metadata={
49
+ verbosity: int | VerbosityMode = field(
50
+ default = VerbosityMode.DETAILED.value,
51
+ metadata = {
34
52
  "description": "The verbosity level of the test output. Default is 2.",
35
- "required": True,
36
- "default": 2
53
+ "default": VerbosityMode.DETAILED.value
37
54
  }
38
55
  )
39
56
 
40
57
  execution_mode : str | ExecutionMode = field(
41
- default=ExecutionMode.SEQUENTIAL,
42
- metadata={
43
- "description": "The mode of test execution. Default is ExecutionMode.SEQUENTIAL",
44
- "required": True,
45
- "default": "ExecutionMode.SEQUENTIAL"
58
+ default = ExecutionMode.SEQUENTIAL.value,
59
+ metadata = {
60
+ "description": "The mode of test execution. Default is SEQUENTIAL",
61
+ "default": ExecutionMode.SEQUENTIAL.value
46
62
  }
47
63
  )
48
64
 
49
65
  max_workers: int = field(
50
- default_factory=lambda : Workers().calculate(),
51
- metadata={
52
- "description": "The maximum number of worker threads/processes to use when running tests in parallel. Default is 4.",
53
- "required": True,
54
- "default": Workers().__class__
66
+ default_factory = lambda : Workers().calculate(),
67
+ metadata = {
68
+ "description": "The maximum number of worker threads/processes to use when running tests in parallel.",
69
+ "default": Workers().calculate()
55
70
  }
56
71
  )
57
72
 
58
73
  fail_fast: bool = field(
59
- default=False,
60
- metadata={
74
+ default = False,
75
+ metadata = {
61
76
  "description": "Whether to stop execution after the first test failure. Default is False.",
62
- "required": True,
63
77
  "default": False
64
78
  }
65
79
  )
66
80
 
67
81
  print_result: bool = field(
68
- default=True,
69
- metadata={
82
+ default = True,
83
+ metadata = {
70
84
  "description": "Whether to print the test results to the console. Default is True.",
71
- "required": True,
72
85
  "default": True
73
86
  }
74
87
  )
75
88
 
76
89
  throw_exception: bool = field(
77
- default=False,
78
- metadata={
90
+ default = False,
91
+ metadata = {
79
92
  "description": "Whether to throw an exception if a test fails. Default is False.",
80
- "required": True,
81
93
  "default": False
82
94
  }
83
95
  )
84
96
 
85
97
  base_path: str = field(
86
- default='tests',
87
- metadata={
98
+ default = 'tests',
99
+ metadata = {
88
100
  "description": "The base directory where tests are located. Default is 'tests'.",
89
- "required": True,
90
101
  "default": 'tests'
91
102
  }
92
103
  )
93
104
 
94
105
  folder_path: str | list = field(
95
- default='*',
96
- metadata={
106
+ default = '*',
107
+ metadata = {
97
108
  "description": "The folder path pattern to search for tests. Default is '*'.",
98
- "required": True,
99
109
  "default": '*'
100
110
  }
101
111
  )
102
112
 
103
113
  pattern: str = field(
104
- default='test_*.py',
105
- metadata={
114
+ default = 'test_*.py',
115
+ metadata = {
106
116
  "description": "The filename pattern to identify test files. Default is 'test_*.py'.",
107
- "required": True,
108
117
  "default": 'test_*.py'
109
118
  }
110
119
  )
111
120
 
112
121
  test_name_pattern: str | None = field(
113
- default=None,
114
- metadata={
122
+ default = None,
123
+ metadata = {
115
124
  "description": "A pattern to match specific test names. Default is None.",
116
- "required": False,
117
125
  "default": None
118
126
  }
119
127
  )
120
128
 
121
129
  tags: List[str] | None = field(
122
- default_factory=lambda:[],
123
- metadata={
130
+ default_factory = lambda: [],
131
+ metadata = {
124
132
  "description": "A list of tags to filter tests. Default is an empty list.",
125
- "required": False,
126
133
  "default": []
127
134
  }
128
135
  )
129
136
 
130
137
  persistent: bool = field(
131
- default=False,
132
- metadata={
138
+ default = False,
139
+ metadata = {
133
140
  "description": "Whether to keep the test results persistent. Default is False.",
134
- "required": True,
135
141
  "default": False
136
142
  }
137
143
  )
138
144
 
139
- persistent_driver: str = field(
140
- default='sqlite',
141
- metadata={
145
+ persistent_driver: str | PersistentDrivers = field(
146
+ default = PersistentDrivers.JSON.value,
147
+ metadata = {
142
148
  "description": "Specifies the driver to use for persisting test results. Supported values: 'sqlite', 'json'. Default is 'sqlite'.",
143
- "required": False,
144
- "default": 'sqlite'
149
+ "default": PersistentDrivers.JSON.value
145
150
  }
146
151
  )
147
152
 
148
153
  web_report: bool = field(
149
- default=False,
150
- metadata={
154
+ default = False,
155
+ metadata = {
151
156
  "description": "Whether to generate a web report for the test results. Default is False.",
152
- "required": True,
153
157
  "default": False
154
158
  }
155
159
  )
156
160
 
157
161
  def __post_init__(self):
158
162
  """
159
- Post-initialization validation for the testing configuration entity.
160
- This method performs type and value checks on the instance attributes to ensure they meet the expected constraints:
161
- - `verbosity` must be an integer between 0 and 2 (inclusive).
162
- - `execution_mode` must not be None.
163
- - `max_workers` must be a positive integer.
164
- - `fail_fast`, `print_result`, and `throw_exception` must be booleans.
165
- - `base_path`, `folder_path`, and `pattern` must be strings.
166
- - `test_name_pattern` must be either a string or None.
167
- - `tags` must be either None or a list of strings.
168
- Raises:
169
- OrionisIntegrityException: If any of the attributes do not meet the specified constraints.
163
+ Validate and normalize configuration options after initialization.
164
+
165
+ This method checks the types and values of all configuration attributes of the Testing class.
166
+ If any attribute is invalid, an OrionisIntegrityException is raised with a descriptive error message.
167
+ It also normalizes enum/string values to their canonical forms where appropriate.
168
+
169
+ Raises
170
+ ------
171
+ OrionisIntegrityException
172
+ If any configuration option is invalid or inconsistent.
170
173
  """
171
174
 
172
- if not isinstance(self.verbosity, int) or self.verbosity < 0 or self.verbosity > 2:
175
+ # Validate the attributes of the Testing dataclass
176
+ if not isinstance(self.verbosity, (int, VerbosityMode)):
173
177
  raise OrionisIntegrityException(
174
- f"Invalid value for 'verbosity': {self.verbosity}. It must be an integer between 0 (silent) and 2 (detailed output)."
178
+ f"Invalid type for 'verbosity': {type(self.verbosity).__name__}. It must be an integer or an instance of VerbosityMode."
175
179
  )
176
180
 
181
+ if isinstance(self.verbosity, int):
182
+ if (self.verbosity < 0 or self.verbosity > 2):
183
+ raise OrionisIntegrityException(
184
+ f"Invalid value for 'verbosity': {self.verbosity}. It must be an integer between 0 (silent) and 2 (detailed output)."
185
+ )
186
+ elif isinstance(self.verbosity, VerbosityMode):
187
+ self.verbosity = self.verbosity.value
188
+
189
+
190
+ # Validate the Excecution Mode
177
191
  if not isinstance(self.execution_mode, (str, ExecutionMode)):
178
192
  raise OrionisIntegrityException(
179
193
  f"Invalid type for 'execution_mode': {type(self.execution_mode).__name__}. It must be a string or an instance of ExecutionMode."
@@ -191,36 +205,50 @@ class Testing:
191
205
  elif isinstance(self.execution_mode, ExecutionMode):
192
206
  self.execution_mode = self.execution_mode.value
193
207
 
208
+ # Validate Max Workers
194
209
  if not isinstance(self.max_workers, int) or self.max_workers < 1:
195
210
  raise OrionisIntegrityException(
196
211
  f"Invalid value for 'max_workers': {self.max_workers}. It must be a positive integer greater than 0."
197
212
  )
198
213
 
214
+ # Real max working calculation
215
+ real_max_working = Workers().calculate()
216
+ if self.max_workers > real_max_working:
217
+ raise OrionisIntegrityException(
218
+ f"Invalid value for 'max_workers': {self.max_workers}. It must be less than or equal to the real maximum workers available: {real_max_working}."
219
+ )
220
+
221
+ # Validate fail_fast attribute
199
222
  if not isinstance(self.fail_fast, bool):
200
223
  raise OrionisIntegrityException(
201
224
  f"Invalid type for 'fail_fast': {type(self.fail_fast).__name__}. It must be a boolean (True or False)."
202
225
  )
203
226
 
227
+ # Validate print_result attribute
204
228
  if not isinstance(self.print_result, bool):
205
229
  raise OrionisIntegrityException(
206
230
  f"Invalid type for 'print_result': {type(self.print_result).__name__}. It must be a boolean (True or False)."
207
231
  )
208
232
 
233
+ # Validate throw_exception attribute
209
234
  if not isinstance(self.throw_exception, bool):
210
235
  raise OrionisIntegrityException(
211
236
  f"Invalid type for 'throw_exception': {type(self.throw_exception).__name__}. It must be a boolean (True or False)."
212
237
  )
213
238
 
239
+ # Validate base_path attribute
214
240
  if not isinstance(self.base_path, str):
215
241
  raise OrionisIntegrityException(
216
242
  f"Invalid type for 'base_path': {type(self.base_path).__name__}. It must be a string representing the base directory for tests."
217
243
  )
218
244
 
245
+ # Validate folder_path attribute
219
246
  if not (isinstance(self.folder_path, str) or isinstance(self.folder_path, list)):
220
247
  raise OrionisIntegrityException(
221
248
  f"Invalid type for 'folder_path': {type(self.folder_path).__name__}. It must be a string or a list of strings representing the folder path pattern."
222
249
  )
223
250
 
251
+ # If folder_path is a list, ensure all elements are strings
224
252
  if isinstance(self.folder_path, list):
225
253
  for i, folder in enumerate(self.folder_path):
226
254
  if not isinstance(folder, str):
@@ -228,16 +256,19 @@ class Testing:
228
256
  f"Invalid type for folder at index {i} in 'folder_path': {type(folder).__name__}. Each folder path must be a string."
229
257
  )
230
258
 
259
+ # Validate pattern attribute
231
260
  if not isinstance(self.pattern, str):
232
261
  raise OrionisIntegrityException(
233
262
  f"Invalid type for 'pattern': {type(self.pattern).__name__}. It must be a string representing the filename pattern for test files."
234
263
  )
235
264
 
265
+ # Validate test_name_pattern attribute
236
266
  if self.test_name_pattern is not None and not isinstance(self.test_name_pattern, str):
237
267
  raise OrionisIntegrityException(
238
268
  f"Invalid type for 'test_name_pattern': {type(self.test_name_pattern).__name__}. It must be a string or None."
239
269
  )
240
270
 
271
+ # Validate tags attribute
241
272
  if self.tags is not None:
242
273
  if not isinstance(self.tags, list):
243
274
  raise OrionisIntegrityException(
@@ -249,52 +280,36 @@ class Testing:
249
280
  f"Invalid type for tag at index {i} in 'tags': {type(tag).__name__}. Each tag must be a string."
250
281
  )
251
282
 
283
+ # Validate persistent attribute
252
284
  if not isinstance(self.persistent, bool):
253
285
  raise OrionisIntegrityException(
254
286
  f"Invalid type for 'persistent': {type(self.persistent).__name__}. It must be a boolean (True or False)."
255
287
  )
256
288
 
289
+ # Validate persistent_driver attribute
257
290
  if self.persistent:
258
- if not isinstance(self.persistent_driver, str):
259
- raise OrionisIntegrityException(
260
- f"Invalid type for 'persistent_driver': {type(self.persistent_driver).__name__}. It must be a string."
261
- )
262
- if self.persistent_driver not in ['sqlite', 'json']:
291
+
292
+ # Validate persistent_driver type and value
293
+ if not isinstance(self.persistent_driver, (str, PersistentDrivers)):
263
294
  raise OrionisIntegrityException(
264
- f"Invalid value for 'persistent_driver': {self.persistent_driver}. It must be one of: ['sqlite', 'json']."
295
+ f"Invalid type for 'persistent_driver': {type(self.persistent_driver).__name__}. It must be a string or an instance of PersistentDrivers."
265
296
  )
266
297
 
298
+ # If persistent_driver is a string, convert it to PersistentDrivers enum
299
+ if isinstance(self.persistent_driver, str):
300
+ options_drivers = PersistentDrivers._member_names_
301
+ _value = str(self.persistent_driver).upper().strip()
302
+ if _value not in options_drivers:
303
+ raise OrionisIntegrityException(
304
+ f"Invalid value for 'persistent_driver': {self.persistent_driver}. It must be one of: {str(options_drivers)}."
305
+ )
306
+ else:
307
+ self.persistent_driver = PersistentDrivers[_value].value
308
+ else:
309
+ self.persistent_driver = self.persistent_driver.value
310
+
311
+ # Validate web_report attribute
267
312
  if not isinstance(self.web_report, bool):
268
313
  raise OrionisIntegrityException(
269
314
  f"Invalid type for 'web_report': {type(self.web_report).__name__}. It must be a boolean (True or False)."
270
- )
271
-
272
- def toDict(self) -> dict:
273
- """
274
- Convert the object to a dictionary representation.
275
- Returns:
276
- dict: A dictionary representation of the Dataclass object.
277
- """
278
- return asdict(self)
279
-
280
- def getFields(self):
281
- """
282
- Retrieves a list of field information for the current dataclass instance.
283
-
284
- Returns:
285
- list: A list of dictionaries, each containing details about a field:
286
- - name (str): The name of the field.
287
- - type (type): The type of the field.
288
- - default: The default value of the field, if specified; otherwise, the value from metadata or None.
289
- - metadata (mapping): The metadata associated with the field.
290
- """
291
- __fields = []
292
- for field in fields(self):
293
- __metadata = dict(field.metadata) or {}
294
- __fields.append({
295
- "name": field.name,
296
- "type": field.type.__name__ if hasattr(field.type, '__name__') else str(field.type),
297
- "default": field.default if (field.default is not None and '_MISSING_TYPE' not in str(field.default)) else __metadata.get('default', None),
298
- "metadata": __metadata
299
- })
300
- return __fields
315
+ )
@@ -1,5 +1,9 @@
1
- from .test_mode import ExecutionMode
1
+ from .mode import ExecutionMode
2
+ from .verbosity import VerbosityMode
3
+ from .drivers import PersistentDrivers
2
4
 
3
5
  __all__ = [
4
- "ExecutionMode"
6
+ "ExecutionMode",
7
+ "VerbosityMode",
8
+ "PersistentDrivers"
5
9
  ]
@@ -0,0 +1,16 @@
1
+ from enum import Enum
2
+
3
+ class PersistentDrivers(Enum):
4
+ """
5
+ Enumeration of supported persistent storage drivers.
6
+
7
+ Attributes
8
+ ----------
9
+ JSON : str
10
+ Represents the JSON file-based storage driver.
11
+ SQLITE : str
12
+ Represents the SQLite database storage driver.
13
+ """
14
+
15
+ JSON = 'json'
16
+ SQLITE = 'sqlite'
@@ -0,0 +1,18 @@
1
+ from enum import Enum
2
+
3
+ class VerbosityMode(Enum):
4
+ """
5
+ Enumeration of verbosity levels for output during testing.
6
+
7
+ Attributes
8
+ ----------
9
+ SILENT : int
10
+ No output will be shown.
11
+ MINIMAL : int
12
+ Minimal output will be displayed.
13
+ DETAILED : int
14
+ Detailed output will be provided (default).
15
+ """
16
+ SILENT = 0 # 0: Silent
17
+ MINIMAL = 1 # 1: Minimal output
18
+ DETAILED = 2 # 2: Detailed output (default)