orionis 0.372.0__py3-none-any.whl → 0.374.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 (99) hide show
  1. orionis/__init__.py +4 -2
  2. orionis/container/facades/facade.py +10 -8
  3. orionis/container/resolver/resolver.py +3 -3
  4. orionis/foundation/application.py +25 -0
  5. orionis/metadata/framework.py +1 -1
  6. orionis/services/introspection/dependencies/entities/callable_dependencies.py +6 -6
  7. orionis/services/introspection/dependencies/entities/class_dependencies.py +7 -7
  8. orionis/services/introspection/dependencies/entities/{resolved_dependencies.py → known_dependencies.py} +1 -1
  9. orionis/services/introspection/dependencies/entities/method_dependencies.py +6 -6
  10. orionis/services/introspection/dependencies/reflection.py +4 -4
  11. orionis/test/arguments/parser.py +187 -0
  12. orionis/test/cases/asynchronous.py +145 -0
  13. orionis/test/cases/synchronous.py +135 -0
  14. orionis/test/contracts/kernel.py +134 -0
  15. orionis/test/contracts/logs.py +125 -0
  16. orionis/test/contracts/parser.py +43 -0
  17. orionis/test/contracts/render.py +30 -0
  18. orionis/test/contracts/unit_test.py +21 -0
  19. orionis/test/core/unit_test.py +104 -23
  20. orionis/test/entities/arguments.py +38 -0
  21. orionis/test/kernel.py +336 -0
  22. orionis/test/output/dumper.py +3 -4
  23. orionis/test/output/printer.py +22 -0
  24. orionis/test/{logs → record}/history.py +25 -9
  25. orionis/test/records/__init__.py +0 -0
  26. orionis/test/records/logs.py +385 -0
  27. orionis/test/view/render.py +8 -5
  28. {orionis-0.372.0.dist-info → orionis-0.374.0.dist-info}/METADATA +1 -1
  29. {orionis-0.372.0.dist-info → orionis-0.374.0.dist-info}/RECORD +93 -88
  30. tests/example/test_example.py +4 -3
  31. tests/foundation/config/app/test_foundation_config_app.py +2 -2
  32. tests/foundation/config/auth/test_foundation_config_auth.py +2 -2
  33. tests/foundation/config/cache/test_foundation_config_cache.py +2 -2
  34. tests/foundation/config/cache/test_foundation_config_cache_file.py +2 -2
  35. tests/foundation/config/cache/test_foundation_config_cache_stores.py +2 -2
  36. tests/foundation/config/cors/test_foundation_config_cors.py +2 -2
  37. tests/foundation/config/database/test_foundation_config_database.py +2 -2
  38. tests/foundation/config/database/test_foundation_config_database_connections.py +2 -2
  39. tests/foundation/config/database/test_foundation_config_database_mysql.py +2 -2
  40. tests/foundation/config/database/test_foundation_config_database_oracle.py +2 -2
  41. tests/foundation/config/database/test_foundation_config_database_pgsql.py +2 -2
  42. tests/foundation/config/database/test_foundation_config_database_sqlite.py +2 -2
  43. tests/foundation/config/filesystems/test_foundation_config_filesystems.py +2 -2
  44. tests/foundation/config/filesystems/test_foundation_config_filesystems_aws.py +2 -2
  45. tests/foundation/config/filesystems/test_foundation_config_filesystems_disks.py +2 -2
  46. tests/foundation/config/filesystems/test_foundation_config_filesystems_local.py +2 -2
  47. tests/foundation/config/filesystems/test_foundation_config_filesystems_public.py +2 -2
  48. tests/foundation/config/logging/test_foundation_config_logging.py +2 -2
  49. tests/foundation/config/logging/test_foundation_config_logging_channels.py +2 -2
  50. tests/foundation/config/logging/test_foundation_config_logging_chunked.py +2 -2
  51. tests/foundation/config/logging/test_foundation_config_logging_daily.py +2 -2
  52. tests/foundation/config/logging/test_foundation_config_logging_hourly.py +2 -2
  53. tests/foundation/config/logging/test_foundation_config_logging_monthly.py +2 -2
  54. tests/foundation/config/logging/test_foundation_config_logging_stack.py +2 -2
  55. tests/foundation/config/logging/test_foundation_config_logging_weekly.py +2 -2
  56. tests/foundation/config/mail/test_foundation_config_mail.py +2 -2
  57. tests/foundation/config/mail/test_foundation_config_mail_file.py +2 -2
  58. tests/foundation/config/mail/test_foundation_config_mail_mailers.py +2 -2
  59. tests/foundation/config/mail/test_foundation_config_mail_smtp.py +2 -2
  60. tests/foundation/config/queue/test_foundation_config_queue.py +2 -5
  61. tests/foundation/config/queue/test_foundation_config_queue_brokers.py +2 -2
  62. tests/foundation/config/queue/test_foundation_config_queue_database.py +3 -2
  63. tests/foundation/config/root/test_foundation_config_root_paths.py +3 -3
  64. tests/foundation/config/session/test_foundation_config_session.py +4 -3
  65. tests/foundation/config/startup/test_foundation_config_startup.py +4 -3
  66. tests/foundation/config/testing/test_foundation_config_testing.py +3 -3
  67. tests/foundation/exceptions/test_foundation_config_exceptions.py +3 -3
  68. tests/metadata/test_metadata_framework.py +2 -2
  69. tests/metadata/test_metadata_package.py +3 -2
  70. tests/services/asynchrony/test_services_asynchrony_coroutine.py +2 -2
  71. tests/services/environment/test_services_environment.py +2 -2
  72. tests/services/inspection/dependencies/test_reflect_dependencies.py +22 -22
  73. tests/services/inspection/reflection/test_reflection_abstract.py +2 -2
  74. tests/services/inspection/reflection/test_reflection_callable.py +2 -2
  75. tests/services/inspection/reflection/test_reflection_concrete.py +2 -2
  76. tests/services/inspection/reflection/test_reflection_instance.py +2 -2
  77. tests/services/inspection/reflection/test_reflection_module.py +2 -2
  78. tests/services/inspection/test_reflection.py +2 -2
  79. tests/services/path/test_services_resolver.py +2 -2
  80. tests/services/system/test_services_system_imports.py +2 -2
  81. tests/services/system/test_services_system_workers.py +3 -2
  82. tests/support/parsers/test_services_parser_exceptions.py +2 -2
  83. tests/support/patterns/singleton/test_patterns_singleton.py +2 -2
  84. tests/support/standard/test_services_std.py +2 -2
  85. tests/support/wrapper/test_services_wrapper_docdict.py +2 -2
  86. tests/testing/test_testing_result.py +4 -6
  87. tests/testing/test_testing_unit.py +9 -10
  88. orionis/test/cases/test_async.py +0 -55
  89. orionis/test/cases/test_case.py +0 -42
  90. orionis/test/cases/test_sync.py +0 -33
  91. orionis/test/contracts/history.py +0 -54
  92. orionis/test/test_suite.py +0 -142
  93. orionis/unittesting.py +0 -64
  94. /orionis/test/{logs → arguments}/__init__.py +0 -0
  95. /orionis/test/entities/{test_result.py → result.py} +0 -0
  96. {orionis-0.372.0.dist-info → orionis-0.374.0.dist-info}/WHEEL +0 -0
  97. {orionis-0.372.0.dist-info → orionis-0.374.0.dist-info}/licenses/LICENCE +0 -0
  98. {orionis-0.372.0.dist-info → orionis-0.374.0.dist-info}/top_level.txt +0 -0
  99. {orionis-0.372.0.dist-info → orionis-0.374.0.dist-info}/zip-safe +0 -0
@@ -0,0 +1,38 @@
1
+ from dataclasses import dataclass
2
+ from typing import Literal, Optional
3
+
4
+ @dataclass
5
+ class TestArguments:
6
+ """
7
+ Parameters for Orionis test execution.
8
+
9
+ Parameters
10
+ ----------
11
+ verbosity : int, default=2
12
+ Level of test output verbosity.
13
+ mode : {'parallel', 'sequential'}, default='parallel'
14
+ Test execution mode. Whether to run tests in parallel or sequentially.
15
+ fail_fast : bool, default=False
16
+ If True, stop execution upon first test failure.
17
+ print_result : bool, default=True
18
+ If True, print test results to the console.
19
+ throw_exception : bool, default=False
20
+ If True, raise exceptions during test execution.
21
+ persistent : bool, default=False
22
+ If True, maintain state between test runs.
23
+ persistent_driver : str, optional
24
+ Driver to use for persistent test execution.
25
+ web_report : bool, default=False
26
+ If True, generate a web-based test report.
27
+ print_output_buffer : bool, default=False
28
+ If True, print the test output buffer.
29
+ """
30
+ verbosity: int = 2
31
+ mode: Literal['parallel', 'sequential'] = 'parallel'
32
+ fail_fast: bool = False
33
+ print_result: bool = True
34
+ throw_exception: bool = False
35
+ persistent: bool = False
36
+ persistent_driver: Optional[str] = None
37
+ web_report: bool = False
38
+ print_output_buffer: bool = False
orionis/test/kernel.py ADDED
@@ -0,0 +1,336 @@
1
+ import gc
2
+ import os
3
+ import re
4
+ from os import walk
5
+ from orionis.foundation.config.testing.entities.testing import Testing as Configuration
6
+ from orionis.foundation.contracts.application import IApplication
7
+ from orionis.test.contracts.kernel import ITestKernel
8
+ from orionis.test.arguments.parser import TestArgumentParser
9
+ from orionis.test.core.unit_test import UnitTest
10
+ from orionis.test.entities.arguments import TestArguments
11
+ from orionis.test.enums.execution_mode import ExecutionMode
12
+ from orionis.test.exceptions import OrionisTestConfigException
13
+
14
+ class TestKernel(ITestKernel):
15
+ """
16
+ Core test kernel for the Orionis testing framework.
17
+
18
+ This class provides the main interface for discovering, configuring, and executing
19
+ test suites within the Orionis framework. It handles test configuration validation,
20
+ test discovery across multiple directories, and orchestrates the execution of
21
+ discovered tests.
22
+
23
+ Parameters
24
+ ----------
25
+ app : IApplication
26
+ The Orionis application instance that provides the testing context.
27
+
28
+ Attributes
29
+ ----------
30
+ __app : IApplication
31
+ Private reference to the application instance.
32
+ __config : Configuration
33
+ Private reference to the testing configuration.
34
+ """
35
+
36
+ def __init__(
37
+ self,
38
+ app: IApplication
39
+ ) -> None:
40
+ """
41
+ Initialize the Orionis test kernel.
42
+
43
+ Parameters
44
+ ----------
45
+ app : IApplication
46
+ The application instance that implements the IApplication interface.
47
+ This provides the context and services needed for test execution.
48
+
49
+ Raises
50
+ ------
51
+ ValueError
52
+ If the provided app is None or not an instance of IApplication.
53
+ """
54
+ # Validate application instance
55
+ if app is None or not isinstance(app, IApplication):
56
+ raise ValueError("The provided application is not a valid instance of IApplication.")
57
+
58
+ # Set the application instance
59
+ self.__app = app
60
+
61
+ def __checkConfiguration(
62
+ self,
63
+ config: Configuration = None,
64
+ **kwargs
65
+ ) -> Configuration:
66
+ """
67
+ Validate and initialize the testing configuration.
68
+
69
+ This method validates the provided configuration or creates a new one from
70
+ keyword arguments. It ensures that the configuration is properly set up
71
+ before test execution begins.
72
+
73
+ Parameters
74
+ ----------
75
+ config : Configuration, optional
76
+ A pre-configured Testing configuration instance. If None, attempts to
77
+ create one from kwargs.
78
+ **kwargs : dict
79
+ Keyword arguments to create a Configuration instance if config is None.
80
+ Must match the Configuration class constructor parameters.
81
+
82
+ Returns
83
+ -------
84
+ bool
85
+ True if configuration validation succeeds.
86
+
87
+ Raises
88
+ ------
89
+ OrionisTestConfigException
90
+ If the configuration is invalid or required fields are missing.
91
+ The exception message includes details about required fields and their types.
92
+ """
93
+ # Check if config is None and kwargs are provided
94
+ if config is None:
95
+ try:
96
+ # Attempt to create a Configuration instance with provided keyword arguments
97
+ config = Configuration(**kwargs)
98
+ except TypeError:
99
+ # If a TypeError occurs, it indicates that the provided arguments do not match the Configuration class
100
+ required_fields = []
101
+ for field in Configuration().getFields():
102
+ required_fields.append(f"{field.get('name')} = (Type: {field.get('type')}, Default: {field.get('default')})")
103
+
104
+ # Raise an exception with a detailed message about the required fields
105
+ raise OrionisTestConfigException(f"The provided configuration is not valid. Please ensure it is an instance of the Configuration class or provide valid keyword arguments. \n{str('\n').join(required_fields)}]")
106
+
107
+ # Assign the configuration to the instance variable
108
+ return config or Configuration()
109
+
110
+ def handle(
111
+ self,
112
+ config: Configuration = None,
113
+ **kwargs
114
+ ) -> UnitTest:
115
+ """
116
+ Execute the complete test discovery and execution pipeline.
117
+
118
+ This is the main entry point for running tests. It validates the configuration,
119
+ discovers test files based on specified patterns and paths, configures the
120
+ test suite, and executes all discovered tests.
121
+
122
+ Parameters
123
+ ----------
124
+ config : Configuration, optional
125
+ A pre-configured Testing configuration instance. If None, attempts to
126
+ create one from kwargs.
127
+ **kwargs : dict
128
+ Keyword arguments to create a Configuration instance if config is None.
129
+ Common parameters include:
130
+ - base_path : str, base directory for test discovery
131
+ - folder_path : str or list, specific folders to search
132
+ - pattern : str, file pattern for test discovery
133
+ - verbosity : int, output verbosity level
134
+ - execution_mode : str, test execution mode
135
+ - max_workers : int, maximum number of worker threads
136
+ - fail_fast : bool, stop on first failure
137
+
138
+ Returns
139
+ -------
140
+ UnitTest
141
+ The configured and executed test suite instance containing all results.
142
+
143
+ Raises
144
+ ------
145
+ OrionisTestConfigException
146
+ If the configuration validation fails.
147
+ """
148
+ # Validate and set configuration
149
+ config = self.__checkConfiguration(config, **kwargs)
150
+
151
+ # Initialize the test suite
152
+ tests = UnitTest()
153
+
154
+ # Assign the application instance to the test suite
155
+ tests.setApplication(self.__app)
156
+
157
+ # Configure the test suite with validated configuration values
158
+ tests.configure(
159
+ verbosity=config.verbosity,
160
+ execution_mode=config.execution_mode,
161
+ max_workers=config.max_workers,
162
+ fail_fast=config.fail_fast,
163
+ print_result=config.print_result,
164
+ throw_exception=config.throw_exception,
165
+ persistent=config.persistent,
166
+ persistent_driver=config.persistent_driver,
167
+ web_report=config.web_report
168
+ )
169
+
170
+ # Extract configuration values for test discovery
171
+ base_path = config.base_path
172
+ folder_path = config.folder_path
173
+ pattern = config.pattern
174
+
175
+ def list_matching_folders(custom_path: str, pattern: str):
176
+ """
177
+ Discover folders containing files that match the specified pattern.
178
+
179
+ This helper function walks through the directory tree starting from
180
+ custom_path and identifies folders that contain files matching the
181
+ given pattern.
182
+
183
+ Parameters
184
+ ----------
185
+ custom_path : str
186
+ The root path to start the search from.
187
+ pattern : str
188
+ The file pattern to match (supports wildcards * and ?).
189
+
190
+ Returns
191
+ -------
192
+ list of str
193
+ List of relative folder paths containing matching files.
194
+ """
195
+ matched_folders = []
196
+ for root, _, files in walk(custom_path):
197
+ for file in files:
198
+ if re.fullmatch(pattern.replace('*', '.*').replace('?', '.'), file):
199
+ relative_path = root.replace(base_path, '').replace('\\', '/').lstrip('/')
200
+ if relative_path not in matched_folders:
201
+ matched_folders.append(relative_path)
202
+ return matched_folders
203
+
204
+ # Discover test folders based on configuration
205
+ discovered_folders = []
206
+ if folder_path == '*':
207
+ # Search all folders under base_path
208
+ discovered_folders.extend(list_matching_folders(base_path, pattern))
209
+ elif isinstance(folder_path, list):
210
+ # Search specific folders provided in the list
211
+ for custom_path in folder_path:
212
+ discovered_folders.extend(list_matching_folders(f"{base_path}/{custom_path}", pattern))
213
+ else:
214
+ # Search single specified folder
215
+ discovered_folders.extend(list_matching_folders(folder_path, pattern))
216
+
217
+ # Add discovered folders to the test suite for execution
218
+ for folder in discovered_folders:
219
+ tests.discoverTestsInFolder(
220
+ folder_path=folder,
221
+ base_path=base_path,
222
+ pattern=pattern,
223
+ test_name_pattern=config.test_name_pattern if config.test_name_pattern else None,
224
+ tags=config.tags if config.tags else None
225
+ )
226
+
227
+ # Execute the test suite and return the results
228
+ tests.run()
229
+
230
+ # Return the test suite instance containing all results
231
+ return tests
232
+
233
+ def handleCLI(
234
+ self,
235
+ sys_argv: list[str],
236
+ ) -> UnitTest:
237
+
238
+ """
239
+ Process command line arguments for test execution.
240
+ This method configures and runs tests based on command line arguments. It extracts
241
+ configuration from the provided TestArguments object, executes the tests, and
242
+ handles output generation.
243
+ Parameters
244
+ ----------
245
+ args : TestArguments
246
+ Command line arguments parsed into a TestArguments object.
247
+ base_path : str, optional
248
+ Base directory to search for test files, by default 'tests'.
249
+ folder_path : str, optional
250
+ Pattern for folder selection within base_path, by default '*'.
251
+ pattern : str, optional
252
+ Filename pattern for test files, by default 'test_*.py'.
253
+ Returns
254
+ -------
255
+ UnitTest
256
+ The test suite instance containing all test results.
257
+ Notes
258
+ -----
259
+ The method supports various test execution options including parallel/sequential
260
+ execution mode, fail fast behavior, and result output configuration.
261
+ """
262
+
263
+ # Validate the provided arguments
264
+ if not isinstance(sys_argv, list):
265
+ raise OrionisTestConfigException("The provided sys_argv must be a list of command line arguments.")
266
+
267
+ # Assign the provided arguments to a TestArguments instance
268
+ parser = TestArgumentParser()
269
+ args:TestArguments = parser.parse(sys_argv)
270
+
271
+ # Extract and validate the configuration from command line arguments
272
+ test = self.handle(
273
+ verbosity = int(args.verbosity),
274
+ execution_mode = ExecutionMode.PARALLEL if args.mode == 'parallel' else ExecutionMode.SEQUENTIAL,
275
+ fail_fast = bool(args.fail_fast),
276
+ print_result = bool(args.print_result),
277
+ throw_exception = bool(args.throw_exception),
278
+ persistent = bool(args.persistent),
279
+ persistent_driver = str(args.persistent_driver) if args.persistent_driver else None,
280
+ web_report = bool(args.web_report)
281
+ )
282
+
283
+ # If requested, print the output buffer
284
+ if args.print_output_buffer:
285
+ test.printOutputBuffer()
286
+
287
+ # Return the test suite instance containing all results
288
+ return test
289
+
290
+ def exit(
291
+ self,
292
+ code: int = 0
293
+ ) -> None:
294
+ """
295
+ Terminate the test execution process and free associated resources.
296
+
297
+ This method performs a clean shutdown of the test kernel by explicitly
298
+ triggering garbage collection to release memory resources and then
299
+ terminating the process with the provided exit code. It ensures that any
300
+ remaining file handles, threads, or other resources are properly released.
301
+
302
+ Parameters
303
+ ----------
304
+ code : int
305
+ The exit code to return to the operating system. Should be 0 for
306
+ successful execution or a non-zero value to indicate an error.
307
+
308
+ Returns
309
+ -------
310
+ None
311
+ This method does not return as it terminates the process.
312
+
313
+ Raises
314
+ ------
315
+ ValueError
316
+ If the provided code is not a valid integer or outside the allowed range.
317
+
318
+ Notes
319
+ -----
320
+ Using os._exit() bypasses normal Python cleanup mechanisms and
321
+ immediately terminates the process. This can be necessary when
322
+ normal sys.exit() would be caught by exception handlers.
323
+ """
324
+ # Validate the exit code
325
+ if not isinstance(code, int):
326
+ raise ValueError("Exit code must be an integer")
327
+
328
+ # Check if the code is within the allowed range (typically 0-255)
329
+ if code < 0 or code > 255:
330
+ raise ValueError("Exit code must be between 0 and 255")
331
+
332
+ # Force garbage collection to free memory
333
+ gc.collect()
334
+
335
+ # Terminate the process immediately without running cleanup handlers
336
+ os._exit(code)
@@ -45,10 +45,9 @@ class TestDumper(ITestDumper):
45
45
  try:
46
46
  if value is None:
47
47
  return False
48
- from orionis.test.cases.test_async import AsyncTestCase
49
- from orionis.test.cases.test_case import TestCase
50
- from orionis.test.cases.test_sync import SyncTestCase
51
- return isinstance(value, (AsyncTestCase, TestCase, SyncTestCase))
48
+ from orionis.test.cases.asynchronous import AsyncTestCase
49
+ from orionis.test.cases.synchronous import SyncTestCase
50
+ return isinstance(value, (AsyncTestCase, SyncTestCase))
52
51
  except Exception:
53
52
  return False
54
53
 
@@ -16,6 +16,28 @@ class TestPrinter(ITestPrinter):
16
16
  def __init__(
17
17
  self
18
18
  ) -> None:
19
+ """
20
+ Initialize the test output printer.
21
+
22
+ This initializes a Rich Console for output rendering, setting up panel
23
+ parameters and debug keywords for test result display.
24
+
25
+ Parameters
26
+ ----------
27
+ None
28
+
29
+ Returns
30
+ -------
31
+ None
32
+
33
+ Notes
34
+ -----
35
+ Sets up the following attributes:
36
+ - __rich_console: Rich Console instance for formatted terminal output
37
+ - __panel_title: Title string for the output panel
38
+ - __panel_width: Width of the output panel (75% of console width)
39
+ - __debbug_keywords: List of keywords for identifying debug calls
40
+ """
19
41
  self.__rich_console = Console()
20
42
  self.__panel_title: str = "🧪 Orionis Framework - Component Test Suite"
21
43
  self.__panel_width: int = int(self.__rich_console.width * 0.75)
@@ -5,9 +5,9 @@ from pathlib import Path
5
5
  from typing import Dict, List, Optional, Tuple
6
6
  from orionis.services.environment.env import Env
7
7
  from orionis.test.exceptions import OrionisTestPersistenceError, OrionisTestValueError
8
- from orionis.test.contracts.history import ITestHistory
8
+ from orionis.test.contracts.logs import ITestLogs
9
9
 
10
- class TestHistory(ITestHistory):
10
+ class TestLogs(ITestLogs):
11
11
 
12
12
  def __init__(
13
13
  self,
@@ -71,7 +71,9 @@ class TestHistory(ITestHistory):
71
71
  # Create a connection to the database, initially set to None
72
72
  self._conn: Optional[sqlite3.Connection] = None
73
73
 
74
- def __connect(self) -> None:
74
+ def __connect(
75
+ self
76
+ ) -> None:
75
77
  """
76
78
  Establishes a connection to the SQLite database if not already connected.
77
79
 
@@ -89,7 +91,9 @@ class TestHistory(ITestHistory):
89
91
  except (sqlite3.Error, Exception) as e:
90
92
  raise OrionisTestPersistenceError(f"Database connection error: {e}")
91
93
 
92
- def __createTableIfNotExists(self) -> bool:
94
+ def __createTableIfNotExists(
95
+ self
96
+ ) -> bool:
93
97
  """
94
98
  Ensures that the test history table exists in the database.
95
99
 
@@ -135,7 +139,10 @@ class TestHistory(ITestHistory):
135
139
  self.__close()
136
140
  self._conn = None
137
141
 
138
- def __insertReport(self, report: Dict) -> bool:
142
+ def __insertReport(
143
+ self,
144
+ report: Dict
145
+ ) -> bool:
139
146
  """
140
147
  Inserts a test report into the history database table.
141
148
 
@@ -272,7 +279,9 @@ class TestHistory(ITestHistory):
272
279
  self.__close()
273
280
  self._conn = None
274
281
 
275
- def __resetDatabase(self) -> bool:
282
+ def __resetDatabase(
283
+ self
284
+ ) -> bool:
276
285
  """
277
286
  Resets the database by dropping the existing table.
278
287
  This method connects to the database, drops the table specified by
@@ -304,7 +313,9 @@ class TestHistory(ITestHistory):
304
313
  self.__close()
305
314
  self._conn = None
306
315
 
307
- def __close(self) -> None:
316
+ def __close(
317
+ self
318
+ ) -> None:
308
319
  """
309
320
  Closes the current database connection.
310
321
  This method checks if a database connection exists. If so, it closes the connection and sets the connection attribute to None.
@@ -318,7 +329,10 @@ class TestHistory(ITestHistory):
318
329
  self._conn.close()
319
330
  self._conn = None
320
331
 
321
- def create(self, report: Dict) -> bool:
332
+ def create(
333
+ self,
334
+ report: Dict
335
+ ) -> bool:
322
336
  """
323
337
  Create a new test report in the history database.
324
338
 
@@ -335,7 +349,9 @@ class TestHistory(ITestHistory):
335
349
  self.__createTableIfNotExists()
336
350
  return self.__insertReport(report)
337
351
 
338
- def reset(self) -> bool:
352
+ def reset(
353
+ self
354
+ ) -> bool:
339
355
  """
340
356
  Reset the history database by dropping the existing table.
341
357
 
File without changes