orionis 0.371.0__py3-none-any.whl → 0.373.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 +9 -0
  2. orionis/container/resolver/resolver.py +3 -3
  3. orionis/foundation/application.py +66 -31
  4. orionis/foundation/contracts/application.py +1 -1
  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 +197 -0
  12. orionis/test/cases/asynchronous.py +145 -0
  13. orionis/test/cases/synchronous.py +135 -0
  14. orionis/test/contracts/kernel.py +99 -0
  15. orionis/test/contracts/logs.py +125 -0
  16. orionis/test/contracts/parser.py +37 -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 +276 -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.371.0.dist-info → orionis-0.373.0.dist-info}/METADATA +1 -1
  29. {orionis-0.371.0.dist-info → orionis-0.373.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.371.0.dist-info → orionis-0.373.0.dist-info}/WHEEL +0 -0
  97. {orionis-0.371.0.dist-info → orionis-0.373.0.dist-info}/licenses/LICENCE +0 -0
  98. {orionis-0.371.0.dist-info → orionis-0.373.0.dist-info}/top_level.txt +0 -0
  99. {orionis-0.371.0.dist-info → orionis-0.373.0.dist-info}/zip-safe +0 -0
orionis/__init__.py CHANGED
@@ -0,0 +1,9 @@
1
+ from orionis.foundation.application import (
2
+ Application as Orionis,
3
+ IApplication as IOrionis
4
+ )
5
+
6
+ __all__ = [
7
+ "Orionis",
8
+ "IOrionis"
9
+ ]
@@ -7,7 +7,7 @@ from orionis.container.enums.lifetimes import Lifetime
7
7
  from orionis.container.exceptions import OrionisContainerException
8
8
  from orionis.services.introspection.callables.reflection import ReflectionCallable
9
9
  from orionis.services.introspection.concretes.reflection import ReflectionConcrete
10
- from orionis.services.introspection.dependencies.entities.resolved_dependencies import ResolvedDependency
10
+ from orionis.services.introspection.dependencies.entities.known_dependencies import KnownDependency
11
11
 
12
12
  class Resolver(IResolver):
13
13
  """
@@ -367,8 +367,8 @@ class Resolver(IResolver):
367
367
  params = {}
368
368
  for param_name, dep in dependencies.resolved.items():
369
369
 
370
- # If the dependency is a ResolvedDependency, resolve it
371
- if isinstance(dep, ResolvedDependency):
370
+ # If the dependency is a KnownDependency, resolve it
371
+ if isinstance(dep, KnownDependency):
372
372
 
373
373
  # If the dependency is a built-in type, raise an exception
374
374
  if dep.module_name == 'builtins':
@@ -3,7 +3,7 @@ from orionis.container.container import Container
3
3
  from orionis.container.contracts.service_provider import IServiceProvider
4
4
  from orionis.foundation.contracts.application import IApplication
5
5
 
6
- class Orionis(Container, IApplication):
6
+ class Application(Container, IApplication):
7
7
  """
8
8
  Application container that manages service providers.
9
9
 
@@ -42,7 +42,7 @@ class Orionis(Container, IApplication):
42
42
  super().__init__()
43
43
 
44
44
  # Check if this specific instance has already been initialized
45
- if not hasattr(self, '_Orionis__initialized'):
45
+ if not hasattr(self, '_Application__initialized'):
46
46
 
47
47
  # Initialize provider-specific attributes
48
48
  self.__providers: List[IServiceProvider] = []
@@ -51,6 +51,69 @@ class Orionis(Container, IApplication):
51
51
  # Mark this instance as initialized
52
52
  self.__initialized = True
53
53
 
54
+ # Bootstrap core services
55
+ self.__bootFramework()
56
+
57
+ def __bootFramework(self) -> None:
58
+ """
59
+ Bootstrap the application by loading internal framework providers.
60
+
61
+ This method should be called once to ensure that core services
62
+ required by the framework are registered before user-defined
63
+ providers are loaded.
64
+ """
65
+ if not self.__booted:
66
+ self.__loadFrameworkProviders()
67
+ self.__loadFrameworksKernel()
68
+
69
+ def __loadFrameworkProviders(self) -> None:
70
+ """
71
+ Load internal framework service providers.
72
+
73
+ This method should register core services required by the framework
74
+ before user-defined providers are loaded.
75
+ """
76
+
77
+ # Import core provider classes
78
+ from orionis.foundation.providers.console_provider import ConsoleProvider
79
+ from orionis.foundation.providers.dumper_provider import DumperProvider
80
+ from orionis.foundation.providers.path_resolver_provider import PathResolverProvider
81
+ from orionis.foundation.providers.progress_bar_provider import ProgressBarProvider
82
+ from orionis.foundation.providers.workers_provider import WorkersProvider
83
+
84
+ # List of core providers to register
85
+ core_providers = [
86
+ ConsoleProvider,
87
+ DumperProvider,
88
+ PathResolverProvider,
89
+ ProgressBarProvider,
90
+ WorkersProvider
91
+ ]
92
+
93
+ # Register each core provider with the application
94
+ for provider_cls in core_providers:
95
+ self.__registerProvider(provider_cls)
96
+
97
+ def __loadFrameworksKernel(self) -> None:
98
+ """
99
+ Load the core framework kernel.
100
+
101
+ This method is responsible for loading the core kernel of the framework,
102
+ which is essential for the application to function correctly.
103
+ """
104
+
105
+ # Import Kernel classes
106
+ from orionis.test.kernel import TestKernel, ITestKernel
107
+
108
+ # List of core kernels to register
109
+ core_kernels = {
110
+ ITestKernel: TestKernel
111
+ }
112
+
113
+ # Register each core kernel with the application
114
+ for kernel_name, kernel_cls in core_kernels.items():
115
+ self.instance(kernel_name, kernel_cls(self))
116
+
54
117
  def __registerProvider(
55
118
  self,
56
119
  provider_cls: Type[IServiceProvider]
@@ -103,32 +166,7 @@ class Orionis(Container, IApplication):
103
166
 
104
167
  self.__booted = True
105
168
 
106
- def __loadFrameworkProviders(self) -> None:
107
- """
108
- Load internal framework service providers.
109
-
110
- This method should register core services required by the framework
111
- before user-defined providers are loaded.
112
- """
113
- from orionis.foundation.providers.console_provider import ConsoleProvider
114
- from orionis.foundation.providers.dumper_provider import DumperProvider
115
- from orionis.foundation.providers.path_resolver_provider import PathResolverProvider
116
- from orionis.foundation.providers.progress_bar_provider import ProgressBarProvider
117
- from orionis.foundation.providers.workers_provider import WorkersProvider
118
-
119
- core_providers = [
120
- ConsoleProvider,
121
- DumperProvider,
122
- PathResolverProvider,
123
- ProgressBarProvider,
124
- WorkersProvider
125
- ]
126
-
127
- for provider_cls in core_providers:
128
- self.__registerProvider(provider_cls)
129
-
130
-
131
- def load(self, providers: List[Type[IServiceProvider]]) -> None:
169
+ def load(self, providers: List[Type[IServiceProvider]] = []) -> None:
132
170
  """
133
171
  Load and boot a list of service providers.
134
172
 
@@ -144,9 +182,6 @@ class Orionis(Container, IApplication):
144
182
  None
145
183
  """
146
184
 
147
- # Load internal framework providers first
148
- self.__loadFrameworkProviders()
149
-
150
185
  # Register and boot each provided service provider
151
186
  for provider_cls in providers:
152
187
  self.__registerProvider(provider_cls)
@@ -28,7 +28,7 @@ class IApplication(IContainer):
28
28
  pass
29
29
 
30
30
  @abstractmethod
31
- def load(self, providers: List[Type[IServiceProvider]]) -> None:
31
+ def load(self, providers: List[Type[IServiceProvider]] = []) -> None:
32
32
  """
33
33
  Load and boot a list of service providers.
34
34
 
@@ -5,7 +5,7 @@
5
5
  NAME = "orionis"
6
6
 
7
7
  # Current version of the framework
8
- VERSION = "0.371.0"
8
+ VERSION = "0.373.0"
9
9
 
10
10
  # Full name of the author or maintainer of the project
11
11
  AUTHOR = "Raul Mauricio Uñate Castro"
@@ -1,6 +1,6 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import Any, Dict, List
3
- from orionis.services.introspection.dependencies.entities.resolved_dependencies import ResolvedDependency
3
+ from orionis.services.introspection.dependencies.entities.known_dependencies import KnownDependency
4
4
  from orionis.services.introspection.exceptions import ReflectionTypeError
5
5
 
6
6
  @dataclass(frozen=True, kw_only=True)
@@ -10,9 +10,9 @@ class CallableDependency:
10
10
 
11
11
  Parameters
12
12
  ----------
13
- resolved : Dict[ResolvedDependency, Any]
13
+ resolved : Dict[KnownDependency, Any]
14
14
  A dictionary mapping resolved dependency descriptors to their corresponding
15
- resolved instances or values for the method. All keys must be ResolvedDependency instances.
15
+ resolved instances or values for the method. All keys must be KnownDependency instances.
16
16
  unresolved : List[str]
17
17
  A list of method parameter names or dependency identifiers that could not be resolved.
18
18
  Must contain only non-empty strings.
@@ -21,12 +21,12 @@ class CallableDependency:
21
21
  ------
22
22
  ReflectionTypeError
23
23
  If types don't match the expected:
24
- - resolved: Dict[ResolvedDependency, Any]
24
+ - resolved: Dict[KnownDependency, Any]
25
25
  - unresolved: List[str]
26
26
  ValueError
27
27
  If resolved contains None keys or unresolved contains empty strings
28
28
  """
29
- resolved: Dict[ResolvedDependency, Any]
29
+ resolved: Dict[KnownDependency, Any]
30
30
  unresolved: List[str]
31
31
 
32
32
  def __post_init__(self):
@@ -37,7 +37,7 @@ class CallableDependency:
37
37
  ------
38
38
  ReflectionTypeError
39
39
  If types don't match the expected:
40
- - resolved: Dict[ResolvedDependency, Any]
40
+ - resolved: Dict[KnownDependency, Any]
41
41
  - unresolved: List[str]
42
42
  ValueError
43
43
  If resolved contains None keys or unresolved contains empty strings
@@ -1,6 +1,6 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import Any, Dict, List
3
- from orionis.services.introspection.dependencies.entities.resolved_dependencies import ResolvedDependency
3
+ from orionis.services.introspection.dependencies.entities.known_dependencies import KnownDependency
4
4
  from orionis.services.introspection.exceptions import ReflectionTypeError
5
5
 
6
6
  @dataclass(frozen=True, kw_only=True)
@@ -10,21 +10,21 @@ class ClassDependency:
10
10
 
11
11
  Parameters
12
12
  ----------
13
- resolved : Dict[ResolvedDependency, Any]
13
+ resolved : Dict[KnownDependency, Any]
14
14
  A dictionary mapping resolved dependency descriptors to their corresponding resolved instances or values.
15
- All keys must be ResolvedDependency instances.
15
+ All keys must be KnownDependency instances.
16
16
  unresolved : List[str]
17
17
  A list of dependency names or identifiers that could not be resolved.
18
18
  Must contain only strings.
19
19
 
20
20
  Attributes
21
21
  ----------
22
- resolved : Dict[ResolvedDependency, Any]
22
+ resolved : Dict[KnownDependency, Any]
23
23
  Dictionary of resolved dependencies.
24
24
  unresolved : List[str]
25
25
  List of unresolved dependency names.
26
26
  """
27
- resolved: Dict[ResolvedDependency, Any]
27
+ resolved: Dict[KnownDependency, Any]
28
28
  unresolved: List[str]
29
29
 
30
30
  def __post_init__(self):
@@ -35,12 +35,12 @@ class ClassDependency:
35
35
  ------
36
36
  ReflectionTypeError
37
37
  If types don't match the expected:
38
- - resolved: Dict[ResolvedDependency, Any]
38
+ - resolved: Dict[KnownDependency, Any]
39
39
  - unresolved: List[str]
40
40
  ValueError
41
41
  If resolved contains None keys or unresolved contains empty strings.
42
42
  """
43
- # Validate 'resolved' is a dict with ResolvedDependency keys
43
+ # Validate 'resolved' is a dict with KnownDependency keys
44
44
  if not isinstance(self.resolved, dict):
45
45
  raise ReflectionTypeError(
46
46
  f"'resolved' must be a dict, got {type(self.resolved).__name__}"
@@ -3,7 +3,7 @@ from typing import Type, Any
3
3
  from orionis.services.introspection.exceptions import ReflectionTypeError
4
4
 
5
5
  @dataclass(frozen=True, kw_only=True)
6
- class ResolvedDependency:
6
+ class KnownDependency:
7
7
  """
8
8
  Represents a fully resolved dependency with complete type information.
9
9
 
@@ -1,6 +1,6 @@
1
1
  from dataclasses import dataclass
2
2
  from typing import Any, Dict, List
3
- from orionis.services.introspection.dependencies.entities.resolved_dependencies import ResolvedDependency
3
+ from orionis.services.introspection.dependencies.entities.known_dependencies import KnownDependency
4
4
  from orionis.services.introspection.exceptions import ReflectionTypeError
5
5
 
6
6
  @dataclass(frozen=True, kw_only=True)
@@ -10,9 +10,9 @@ class MethodDependency:
10
10
 
11
11
  Parameters
12
12
  ----------
13
- resolved : Dict[ResolvedDependency, Any]
13
+ resolved : Dict[KnownDependency, Any]
14
14
  A dictionary mapping resolved dependency descriptors to their corresponding
15
- resolved instances or values for the method. All keys must be ResolvedDependency instances.
15
+ resolved instances or values for the method. All keys must be KnownDependency instances.
16
16
  unresolved : List[str]
17
17
  A list of method parameter names or dependency identifiers that could not be resolved.
18
18
  Must contain only non-empty strings.
@@ -21,12 +21,12 @@ class MethodDependency:
21
21
  ------
22
22
  ReflectionTypeError
23
23
  If types don't match the expected:
24
- - resolved: Dict[ResolvedDependency, Any]
24
+ - resolved: Dict[KnownDependency, Any]
25
25
  - unresolved: List[str]
26
26
  ValueError
27
27
  If resolved contains None keys or unresolved contains empty strings
28
28
  """
29
- resolved: Dict[ResolvedDependency, Any]
29
+ resolved: Dict[KnownDependency, Any]
30
30
  unresolved: List[str]
31
31
 
32
32
  def __post_init__(self):
@@ -37,7 +37,7 @@ class MethodDependency:
37
37
  ------
38
38
  ReflectionTypeError
39
39
  If types don't match the expected:
40
- - resolved: Dict[ResolvedDependency, Any]
40
+ - resolved: Dict[KnownDependency, Any]
41
41
  - unresolved: List[str]
42
42
  ValueError
43
43
  If resolved contains None keys or unresolved contains empty strings
@@ -4,7 +4,7 @@ from orionis.services.introspection.dependencies.contracts.reflection import IRe
4
4
  from orionis.services.introspection.dependencies.entities.callable_dependencies import CallableDependency
5
5
  from orionis.services.introspection.dependencies.entities.class_dependencies import ClassDependency
6
6
  from orionis.services.introspection.dependencies.entities.method_dependencies import MethodDependency
7
- from orionis.services.introspection.dependencies.entities.resolved_dependencies import ResolvedDependency
7
+ from orionis.services.introspection.dependencies.entities.known_dependencies import KnownDependency
8
8
  from orionis.services.introspection.exceptions import ReflectionValueError
9
9
 
10
10
  class ReflectDependencies(IReflectDependencies):
@@ -114,7 +114,7 @@ class ReflectDependencies(IReflectDependencies):
114
114
  # If the parameter has an annotation, it is added to the list of resolved dependencies
115
115
  if param.annotation is not param.empty:
116
116
  module_path = param.annotation.__module__
117
- resolved_dependencies[param_name] = ResolvedDependency(
117
+ resolved_dependencies[param_name] = KnownDependency(
118
118
  module_name=module_path,
119
119
  class_name=param.annotation.__name__,
120
120
  type=param.annotation,
@@ -165,7 +165,7 @@ class ReflectDependencies(IReflectDependencies):
165
165
  # If the parameter has an annotation, it is added to the list of resolved dependencies
166
166
  if param.annotation is not param.empty:
167
167
  module_path = param.annotation.__module__
168
- resolved_dependencies[param_name] = ResolvedDependency(
168
+ resolved_dependencies[param_name] = KnownDependency(
169
169
  module_name=module_path,
170
170
  class_name=param.annotation.__name__,
171
171
  type=param.annotation,
@@ -216,7 +216,7 @@ class ReflectDependencies(IReflectDependencies):
216
216
  # If the parameter has an annotation, it is added to the list of resolved dependencies
217
217
  if param.annotation is not param.empty:
218
218
  module_path = param.annotation.__module__
219
- resolved_dependencies[param_name] = ResolvedDependency(
219
+ resolved_dependencies[param_name] = KnownDependency(
220
220
  module_name=module_path,
221
221
  class_name=param.annotation.__name__,
222
222
  type=param.annotation,
@@ -0,0 +1,197 @@
1
+ import argparse
2
+ from orionis.test.contracts.parser import ITestArgumentParser
3
+ from orionis.test.entities.arguments import TestArguments
4
+
5
+ class TestArgumentParser(ITestArgumentParser):
6
+ """
7
+ A parser class for handling test command-line arguments.
8
+
9
+ This class encapsulates the logic for creating and configuring the argument parser
10
+ for the Orionis test runner, providing a clean interface for parsing test arguments.
11
+ """
12
+
13
+ def __init__(
14
+ self
15
+ ) -> None:
16
+ """Initialize the argument parser with all required arguments."""
17
+ self.parser = self.__create()
18
+
19
+ def __create(
20
+ self
21
+ ) -> argparse.ArgumentParser:
22
+ """
23
+ Create and configure the argument parser with all test-related arguments.
24
+
25
+ Returns
26
+ -------
27
+ argparse.ArgumentParser
28
+ The configured argument parser instance.
29
+ """
30
+ parser = argparse.ArgumentParser(description="Run Orionis tests.")
31
+
32
+ # Basic test configuration
33
+ parser.add_argument(
34
+ '--verbosity',
35
+ type=int,
36
+ default=2,
37
+ help='Verbosity level (default: 2)'
38
+ )
39
+
40
+ parser.add_argument(
41
+ '--mode',
42
+ choices=['parallel', 'sequential'],
43
+ default='parallel',
44
+ help='Execution mode for tests (default: parallel)'
45
+ )
46
+
47
+ # Fail fast configuration
48
+ parser.add_argument(
49
+ '--fail_fast',
50
+ dest='fail_fast',
51
+ action='store_true',
52
+ help='Stop on first failure'
53
+ )
54
+ parser.add_argument(
55
+ '--no_fail_fast',
56
+ dest='fail_fast',
57
+ action='store_false',
58
+ help='Do not stop on first failure (default)'
59
+ )
60
+ parser.set_defaults(fail_fast=False)
61
+
62
+ # Print result configuration
63
+ parser.add_argument(
64
+ '--print_result',
65
+ dest='print_result',
66
+ action='store_true',
67
+ help='Print test results to console (default)'
68
+ )
69
+ parser.add_argument(
70
+ '--no_print_result',
71
+ dest='print_result',
72
+ action='store_false',
73
+ help='Do not print test results to console'
74
+ )
75
+ parser.set_defaults(print_result=True)
76
+
77
+ # Exception handling configuration
78
+ parser.add_argument(
79
+ '--throw_exception',
80
+ dest='throw_exception',
81
+ action='store_true',
82
+ help='Throw exception on test failure'
83
+ )
84
+ parser.add_argument(
85
+ '--no_throw_exception',
86
+ dest='throw_exception',
87
+ action='store_false',
88
+ help='Do not throw exception on test failure (default)'
89
+ )
90
+ parser.set_defaults(throw_exception=False)
91
+
92
+ # Persistent mode configuration
93
+ parser.add_argument(
94
+ '--persistent',
95
+ dest='persistent',
96
+ action='store_true',
97
+ help='Run tests in persistent mode'
98
+ )
99
+ parser.add_argument(
100
+ '--no_persistent',
101
+ dest='persistent',
102
+ action='store_false',
103
+ help='Do not run tests in persistent mode (default)'
104
+ )
105
+ parser.set_defaults(persistent=False)
106
+
107
+ parser.add_argument(
108
+ '--persistent_driver',
109
+ type=str,
110
+ default=None,
111
+ help='Persistent driver to use (default: None)'
112
+ )
113
+
114
+ # Web report configuration
115
+ parser.add_argument(
116
+ '--web_report',
117
+ dest='web_report',
118
+ action='store_true',
119
+ help='Generate web report'
120
+ )
121
+ parser.add_argument(
122
+ '--no_web_report',
123
+ dest='web_report',
124
+ action='store_false',
125
+ help='Do not generate web report (default)'
126
+ )
127
+ parser.set_defaults(web_report=False)
128
+
129
+ # Output buffer configuration
130
+ parser.add_argument(
131
+ '--print_output_buffer',
132
+ dest='print_output_buffer',
133
+ action='store_true',
134
+ help='Print output buffer (for CI integrations)'
135
+ )
136
+ parser.add_argument(
137
+ '--no_print_output_buffer',
138
+ dest='print_output_buffer',
139
+ action='store_false',
140
+ help='Do not print output buffer (default)'
141
+ )
142
+ parser.set_defaults(print_output_buffer=False)
143
+
144
+ return parser
145
+
146
+ def parse(
147
+ self,
148
+ args=None
149
+ ) -> TestArguments:
150
+ """
151
+ Parse command line arguments and return TestArguments object.
152
+
153
+ Parameters
154
+ ----------
155
+ args : list, optional
156
+ List of arguments to parse. If None, uses sys.argv.
157
+
158
+ Returns
159
+ -------
160
+ TestArguments
161
+ Parsed test arguments object.
162
+ """
163
+ return self.parser.parse_args(args)
164
+
165
+ def help(
166
+ self
167
+ ) -> None:
168
+ """Print help message for the test runner."""
169
+ self.parser.print_help()
170
+
171
+ def test_parser_init() -> TestArgumentParser:
172
+ """
173
+ Factory function to create a TestArgumentParser instance.
174
+
175
+ Returns
176
+ -------
177
+ TestArgumentParser
178
+ A new instance of the test argument parser.
179
+ """
180
+ return TestArgumentParser()
181
+
182
+ def cli_test_args(args=None) -> TestArguments:
183
+ """
184
+ Convenience function to quickly parse test arguments.
185
+
186
+ Parameters
187
+ ----------
188
+ args : list, optional
189
+ List of arguments to parse. If None, uses sys.argv.
190
+
191
+ Returns
192
+ -------
193
+ TestArguments
194
+ Parsed test arguments object.
195
+ """
196
+ parser = test_parser_init()
197
+ return parser.parse(args)