orionis 0.641.0__py3-none-any.whl → 0.643.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- orionis/console/commands/version.py +29 -0
- orionis/console/core/reactor.py +4 -2
- orionis/metadata/framework.py +1 -1
- orionis/services/introspection/instances/reflection.py +1 -1
- orionis/test/core/unit_test.py +67 -47
- {orionis-0.641.0.dist-info → orionis-0.643.0.dist-info}/METADATA +1 -1
- {orionis-0.641.0.dist-info → orionis-0.643.0.dist-info}/RECORD +10 -10
- {orionis-0.641.0.dist-info → orionis-0.643.0.dist-info}/WHEEL +0 -0
- {orionis-0.641.0.dist-info → orionis-0.643.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.641.0.dist-info → orionis-0.643.0.dist-info}/top_level.txt +0 -0
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import List
|
|
2
|
+
from orionis.console.args.argument import CLIArgument
|
|
1
3
|
from orionis.console.base.command import BaseCommand
|
|
2
4
|
from orionis.console.exceptions import CLIOrionisRuntimeError
|
|
3
5
|
from rich.console import Console
|
|
@@ -30,6 +32,29 @@ class VersionCommand(BaseCommand):
|
|
|
30
32
|
# Command description
|
|
31
33
|
description: str = "Displays the current Orionis framework version and metadata, including author, Python requirements, documentation, and repository links."
|
|
32
34
|
|
|
35
|
+
async def options(self) -> List[CLIArgument]:
|
|
36
|
+
"""
|
|
37
|
+
Defines the command-line options available for the `make:command` command.
|
|
38
|
+
|
|
39
|
+
This method specifies the arguments that can be passed to the command when it is invoked
|
|
40
|
+
from the CLI. It includes both required and optional arguments, each represented as a
|
|
41
|
+
`CLIArgument` instance.
|
|
42
|
+
|
|
43
|
+
Returns
|
|
44
|
+
-------
|
|
45
|
+
List[CLIArgument]
|
|
46
|
+
A list of `CLIArgument` objects representing the available command-line options.
|
|
47
|
+
"""
|
|
48
|
+
|
|
49
|
+
return [
|
|
50
|
+
CLIArgument(
|
|
51
|
+
flags=["--without-console"],
|
|
52
|
+
type=bool,
|
|
53
|
+
help="Return only the version string, without console output.",
|
|
54
|
+
required=False
|
|
55
|
+
)
|
|
56
|
+
]
|
|
57
|
+
|
|
33
58
|
def handle(self, console: Console) -> str:
|
|
34
59
|
"""
|
|
35
60
|
Executes the version command to display the current Orionis framework version and metadata.
|
|
@@ -55,6 +80,10 @@ class VersionCommand(BaseCommand):
|
|
|
55
80
|
"""
|
|
56
81
|
try:
|
|
57
82
|
|
|
83
|
+
# If the --without-console flag is set, return just the version string
|
|
84
|
+
if self.argument("without_console", False):
|
|
85
|
+
return framework.VERSION
|
|
86
|
+
|
|
58
87
|
# Compose the main information strings using framework metadata
|
|
59
88
|
title = f"[bold yellow]{framework.NAME.capitalize()} Framework[/bold yellow] [white]v{framework.VERSION}[/white]"
|
|
60
89
|
author = f"[bold]Author:[/bold] {framework.AUTHOR} | [bold]Email:[/bold] {framework.AUTHOR_EMAIL}"
|
orionis/console/core/reactor.py
CHANGED
|
@@ -970,7 +970,8 @@ class Reactor(IReactor):
|
|
|
970
970
|
output = await self.__app.callAsync(command_instance, 'handle')
|
|
971
971
|
|
|
972
972
|
# Calculate elapsed time and log completion with DONE state if command.timestamps are enabled
|
|
973
|
-
|
|
973
|
+
self.__performance_counter.stop()
|
|
974
|
+
elapsed_time = round(self.__performance_counter.getSeconds(), 2)
|
|
974
975
|
if command.timestamps:
|
|
975
976
|
self.__executer.done(program=signature, time=f"{elapsed_time}s")
|
|
976
977
|
|
|
@@ -986,7 +987,8 @@ class Reactor(IReactor):
|
|
|
986
987
|
self.__logger.error(f"Command '{signature}' execution failed: {e}")
|
|
987
988
|
|
|
988
989
|
# Calculate elapsed time and log failure with ERROR state if command.timestamps are enabled
|
|
989
|
-
|
|
990
|
+
self.__performance_counter.stop()
|
|
991
|
+
elapsed_time = round(self.__performance_counter.getSeconds(), 2)
|
|
990
992
|
if command.timestamps:
|
|
991
993
|
self.__executer.fail(program=signature, time=f"{elapsed_time}s")
|
|
992
994
|
|
orionis/metadata/framework.py
CHANGED
|
@@ -279,7 +279,7 @@ class ReflectionInstance(IReflectionInstance):
|
|
|
279
279
|
bool
|
|
280
280
|
True if the attribute exists
|
|
281
281
|
"""
|
|
282
|
-
return name in self.getAttributes()
|
|
282
|
+
return name in self.getAttributes() or hasattr(self._instance, name)
|
|
283
283
|
|
|
284
284
|
def getAttribute(self, name: str, default: Any = None) -> Any:
|
|
285
285
|
"""
|
orionis/test/core/unit_test.py
CHANGED
|
@@ -90,6 +90,12 @@ class UnitTest(IUnitTest):
|
|
|
90
90
|
# Suppress overly verbose asyncio logging during test execution
|
|
91
91
|
logging.getLogger("asyncio").setLevel(logging.ERROR)
|
|
92
92
|
|
|
93
|
+
# List of common setup/teardown methods to inspect for debug calls
|
|
94
|
+
self.__commonMethods = [
|
|
95
|
+
'setUp', 'tearDown', 'onSetup', 'onTeardown',
|
|
96
|
+
'asyncSetUp', 'asyncTearDown', 'onAsyncSetup', 'onAsyncTeardown'
|
|
97
|
+
]
|
|
98
|
+
|
|
93
99
|
# Store the application instance for dependency injection and configuration access
|
|
94
100
|
self.__app: IApplication = app
|
|
95
101
|
|
|
@@ -649,9 +655,8 @@ class UnitTest(IUnitTest):
|
|
|
649
655
|
# Gather method names to inspect: main test method and common setup/teardown hooks
|
|
650
656
|
rf_instance = ReflectionInstance(test_case)
|
|
651
657
|
method_name = rf_instance.getAttribute("_testMethodName")
|
|
652
|
-
extra_methods = ["setUp", "tearDown", "onSetup", "onTeardown"]
|
|
653
658
|
method_names_to_check = [method_name] if method_name else []
|
|
654
|
-
method_names_to_check += [m for m in
|
|
659
|
+
method_names_to_check += [m for m in self.__commonMethods if rf_instance.hasMethod(m)]
|
|
655
660
|
|
|
656
661
|
# Inspect each method's source code for debug keywords
|
|
657
662
|
for mname in method_names_to_check:
|
|
@@ -877,10 +882,10 @@ class UnitTest(IUnitTest):
|
|
|
877
882
|
"""
|
|
878
883
|
Inject dependencies into a single test case if required, returning a TestSuite containing the resolved test case.
|
|
879
884
|
|
|
880
|
-
This method uses reflection to inspect the test method for dependency requirements.
|
|
881
|
-
it injects them into the test method. Supports both synchronous and asynchronous test
|
|
882
|
-
wrapped to run in an event loop. If dependencies cannot be resolved
|
|
883
|
-
within a TestSuite.
|
|
885
|
+
This method uses reflection to inspect the test method and common setup/teardown methods for dependency requirements.
|
|
886
|
+
If dependencies are resolved, it injects them into the test method. Supports both synchronous and asynchronous test
|
|
887
|
+
methods: async methods are wrapped to run in an event loop. If dependencies cannot be resolved or an error occurs,
|
|
888
|
+
the original test case is returned as-is within a TestSuite.
|
|
884
889
|
|
|
885
890
|
Parameters
|
|
886
891
|
----------
|
|
@@ -904,71 +909,87 @@ class UnitTest(IUnitTest):
|
|
|
904
909
|
- If dependencies are resolved, injects them into the test method.
|
|
905
910
|
- Supports async test methods by running them in an event loop.
|
|
906
911
|
- If dependencies are unresolved or an error occurs, the original test case is returned.
|
|
912
|
+
- The return value is always a unittest.TestSuite containing either the dependency-injected test case or the original test case.
|
|
907
913
|
"""
|
|
908
914
|
|
|
909
915
|
# Create a new TestSuite to hold the resolved test case
|
|
910
916
|
suite = unittest.TestSuite()
|
|
911
917
|
|
|
912
918
|
try:
|
|
913
|
-
|
|
914
919
|
# Use reflection to inspect the test case for dependency requirements
|
|
915
920
|
rf_instance = ReflectionInstance(test_case)
|
|
916
|
-
method_name = rf_instance.getAttribute("_testMethodName", None)
|
|
917
921
|
|
|
918
|
-
# If
|
|
919
|
-
if not
|
|
922
|
+
# If reflection fails or method name is missing, return the original test case
|
|
923
|
+
if not rf_instance.hasAttribute("_testMethodName"):
|
|
920
924
|
return test_case
|
|
921
925
|
|
|
922
|
-
#
|
|
923
|
-
|
|
926
|
+
# Iterate over the main test method and common setup/teardown methods
|
|
927
|
+
for method_name in [
|
|
928
|
+
rf_instance.getAttribute("_testMethodName"),
|
|
929
|
+
*self.__commonMethods
|
|
930
|
+
]:
|
|
924
931
|
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
932
|
+
# Skip if the method does not exist on the class
|
|
933
|
+
if not method_name or not rf_instance.hasMethod(method_name):
|
|
934
|
+
continue
|
|
928
935
|
|
|
929
|
-
|
|
930
|
-
|
|
936
|
+
# Obtain the dependencies of the method
|
|
937
|
+
dependencies = rf_instance.getMethodDependencies(method_name)
|
|
931
938
|
|
|
932
|
-
#
|
|
933
|
-
|
|
939
|
+
# Skip if the method has unresolved dependencies
|
|
940
|
+
if dependencies.unresolved:
|
|
941
|
+
continue
|
|
934
942
|
|
|
935
|
-
#
|
|
936
|
-
|
|
943
|
+
# If dependencies are resolved, inject them into the test method
|
|
944
|
+
if dependencies.resolved:
|
|
937
945
|
|
|
938
|
-
|
|
939
|
-
|
|
946
|
+
# Get the test case class
|
|
947
|
+
test_cls = rf_instance.getClass()
|
|
940
948
|
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
rf_instance.getClassName(),
|
|
944
|
-
dependencies
|
|
945
|
-
)
|
|
949
|
+
# Create a ReflectionConcrete instance for the test case class
|
|
950
|
+
rf_concrete = ReflectionConcrete(test_cls)
|
|
946
951
|
|
|
947
|
-
|
|
948
|
-
|
|
952
|
+
# Get the original test method
|
|
953
|
+
original_method = rf_concrete.getAttribute(method_name)
|
|
949
954
|
|
|
950
|
-
#
|
|
951
|
-
|
|
952
|
-
|
|
955
|
+
# Resolve the actual arguments to inject
|
|
956
|
+
resolved_args = self.__app.resolveDependencyArguments(
|
|
957
|
+
rf_instance.getClassName(),
|
|
958
|
+
dependencies
|
|
959
|
+
)
|
|
953
960
|
|
|
954
|
-
#
|
|
955
|
-
|
|
956
|
-
return asyncio.run(async_wrapper(self_instance))
|
|
961
|
+
# If the test method is asynchronous, wrap it to run in an event loop
|
|
962
|
+
if asyncio.iscoroutinefunction(original_method):
|
|
957
963
|
|
|
958
|
-
|
|
959
|
-
|
|
964
|
+
# Define an async wrapper to inject dependencies
|
|
965
|
+
async def async_wrapper(self_instance):
|
|
966
|
+
return await original_method(self_instance, **resolved_args)
|
|
960
967
|
|
|
961
|
-
|
|
968
|
+
# Wrap with a sync function for unittest compatibility
|
|
969
|
+
def sync_wrapper(self_instance):
|
|
970
|
+
try:
|
|
971
|
+
loop = asyncio.get_running_loop()
|
|
972
|
+
except RuntimeError:
|
|
973
|
+
loop = None
|
|
974
|
+
if loop and loop.is_running():
|
|
975
|
+
return loop.create_task(async_wrapper(self_instance))
|
|
976
|
+
else:
|
|
977
|
+
return asyncio.run(async_wrapper(self_instance))
|
|
978
|
+
|
|
979
|
+
# Bind the wrapped method to the test case instance
|
|
980
|
+
bound_method = sync_wrapper.__get__(test_case, test_cls)
|
|
962
981
|
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
982
|
+
else:
|
|
983
|
+
|
|
984
|
+
# For synchronous methods, inject dependencies directly
|
|
985
|
+
def wrapper(self_instance):
|
|
986
|
+
return original_method(self_instance, **resolved_args)
|
|
966
987
|
|
|
967
|
-
|
|
968
|
-
|
|
988
|
+
# Bind the wrapped method to the test case instance
|
|
989
|
+
bound_method = wrapper.__get__(test_case, test_cls)
|
|
969
990
|
|
|
970
|
-
|
|
971
|
-
|
|
991
|
+
# Replace the test method with the dependency-injected version
|
|
992
|
+
rf_instance.setMethod(method_name, bound_method)
|
|
972
993
|
|
|
973
994
|
# Add the (possibly resolved) test case to the suite
|
|
974
995
|
suite.addTest(rf_instance.getInstance())
|
|
@@ -977,7 +998,6 @@ class UnitTest(IUnitTest):
|
|
|
977
998
|
return suite
|
|
978
999
|
|
|
979
1000
|
except Exception:
|
|
980
|
-
|
|
981
1001
|
# On error, return the original test case
|
|
982
1002
|
return test_case
|
|
983
1003
|
|
|
@@ -17,7 +17,7 @@ orionis/console/commands/make_command.py,sha256=EbTicRHGf7uZ78MSDwZpQMDTB0MvwATc
|
|
|
17
17
|
orionis/console/commands/scheduler_list.py,sha256=Wtjy73fpcjI6GGsJg6BHWVUXItzHbY1QLEhryXpCLcs,4770
|
|
18
18
|
orionis/console/commands/scheduler_work.py,sha256=iPTgP7gOmTPr__TltYQWiqbDXbCP2njuO_2fCzwmMuc,5778
|
|
19
19
|
orionis/console/commands/test.py,sha256=LXtl918TmYhg0sjBiCfbsvaXUmCLqwCXTazmy7AJhlE,2445
|
|
20
|
-
orionis/console/commands/version.py,sha256=
|
|
20
|
+
orionis/console/commands/version.py,sha256=u5_8CfnEVdS3VSME8rbP6o3Z0XFZ30nSz8uHdahBAoY,4766
|
|
21
21
|
orionis/console/contracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
22
22
|
orionis/console/contracts/base_command.py,sha256=UlDN41Ts0ulxM-B2kgeKNr9_gNv_0LCth_pon1os-8U,7617
|
|
23
23
|
orionis/console/contracts/base_scheduler.py,sha256=RSxEW57MoMU3pXfliIrQw9WuMk95p-xHXi1yACp1qsU,7728
|
|
@@ -33,7 +33,7 @@ orionis/console/contracts/reactor.py,sha256=iT6ShoCutAWEeJzOf_PK7CGXi9TgrOD5tewH
|
|
|
33
33
|
orionis/console/contracts/schedule.py,sha256=xtXgp4BPhvhg3YSM4mrIdbyoBdr4OJBi1gBM_kJN5UQ,13694
|
|
34
34
|
orionis/console/contracts/schedule_event_listener.py,sha256=h06qsBxuEMD3KLSyu0JXdUDHlQW19BX9lA09Qrh2QXg,3818
|
|
35
35
|
orionis/console/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
|
-
orionis/console/core/reactor.py,sha256=
|
|
36
|
+
orionis/console/core/reactor.py,sha256=x_bRFLBq5MiKZdlMG1gZR1GCZgFkUDnG5l_nh2YKiR8,44044
|
|
37
37
|
orionis/console/dumper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
38
38
|
orionis/console/dumper/debug.py,sha256=p8uflSXeDJDrVM9mZY4JMYEus73Z6TsLnQQtgP0QUak,22427
|
|
39
39
|
orionis/console/dynamic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -217,7 +217,7 @@ orionis/foundation/providers/scheduler_provider.py,sha256=IrPQJwvQVLRm5Qnz0Cxon4
|
|
|
217
217
|
orionis/foundation/providers/testing_provider.py,sha256=eI1p2lUlxl25b5Z487O4nmqLE31CTDb4c3Q21xFadkE,1615
|
|
218
218
|
orionis/foundation/providers/workers_provider.py,sha256=GdHENYV_yGyqmHJHn0DCyWmWId5xWjD48e6Zq2PGCWY,1674
|
|
219
219
|
orionis/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
220
|
-
orionis/metadata/framework.py,sha256=
|
|
220
|
+
orionis/metadata/framework.py,sha256=eMaGl9vrCG8j8pnG9UGVptLGI-FoeB4-1fD9cCIkSis,4089
|
|
221
221
|
orionis/metadata/package.py,sha256=k7Yriyp5aUcR-iR8SK2ec_lf0_Cyc-C7JczgXa-I67w,16039
|
|
222
222
|
orionis/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
223
223
|
orionis/services/asynchrony/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -280,7 +280,7 @@ orionis/services/introspection/dependencies/entities/resolve_argument.py,sha256=
|
|
|
280
280
|
orionis/services/introspection/exceptions/__init__.py,sha256=uVRbnndapr9veJps8EzFJeLItxnMEbjUDdPBy3dQbeM,221
|
|
281
281
|
orionis/services/introspection/exceptions/introspection.py,sha256=Qd021psWiXyY9HQVNWIBVZ3KNfHGSgq8NL4btUTR8tg,2532
|
|
282
282
|
orionis/services/introspection/instances/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
283
|
-
orionis/services/introspection/instances/reflection.py,sha256=
|
|
283
|
+
orionis/services/introspection/instances/reflection.py,sha256=ziyaJ7zjlvX0wkbpm7tZ4i5em9UxGdCf2lsFmNVrr_4,58528
|
|
284
284
|
orionis/services/introspection/instances/contracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
285
285
|
orionis/services/introspection/instances/contracts/reflection.py,sha256=OBZ7vI6KsII76oqIF63v1I-msh94_xGfhPZQvqAVLgY,20834
|
|
286
286
|
orionis/services/introspection/modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -371,7 +371,7 @@ orionis/test/contracts/render.py,sha256=wpDQzUtT0r8KFZ7zPcxWHXQ1EVNKxzA_rZ6ZKUcZ
|
|
|
371
371
|
orionis/test/contracts/test_result.py,sha256=SNXJ2UerkweYn7uCT0i0HmMGP0XBrL_9KJs-0ZvIYU4,4002
|
|
372
372
|
orionis/test/contracts/unit_test.py,sha256=EyidHoOPJItwgkBWGYY1TymbNklyn2EUXnghVvW4htc,4652
|
|
373
373
|
orionis/test/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
374
|
-
orionis/test/core/unit_test.py,sha256
|
|
374
|
+
orionis/test/core/unit_test.py,sha256=-T5QS7mWYykOX28Q-dVCP1JoOwwlIzFLlOjZRvYguOU,72500
|
|
375
375
|
orionis/test/entities/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
376
376
|
orionis/test/entities/result.py,sha256=eZ6UIqGmFW8FZ9x8PB_MZbLAc-SAuUyi4FUcMYIZzGo,4777
|
|
377
377
|
orionis/test/enums/__init__.py,sha256=M3imAgMvKFTKg55FbtVoY3zxj7QRY9AfaUWxiSZVvn4,66
|
|
@@ -404,8 +404,8 @@ orionis/test/validators/workers.py,sha256=rWcdRexINNEmGaO7mnc1MKUxkHKxrTsVuHgbnI
|
|
|
404
404
|
orionis/test/view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
405
405
|
orionis/test/view/render.py,sha256=R55ykeRs0wDKcdTf4O1YZ8GDHTFmJ0IK6VQkbJkYUvo,5571
|
|
406
406
|
orionis/test/view/report.stub,sha256=QLqqCdRoENr3ECiritRB3DO_MOjRQvgBh5jxZ3Hs1r0,28189
|
|
407
|
-
orionis-0.
|
|
408
|
-
orionis-0.
|
|
409
|
-
orionis-0.
|
|
410
|
-
orionis-0.
|
|
411
|
-
orionis-0.
|
|
407
|
+
orionis-0.643.0.dist-info/licenses/LICENCE,sha256=JhC-z_9mbpUrCfPjcl3DhDA8trNDMzb57cvRSam1avc,1463
|
|
408
|
+
orionis-0.643.0.dist-info/METADATA,sha256=I1M9inorrXvliOKu3GxjeeGG0K8QMvrAIuDbh0_Cum0,4772
|
|
409
|
+
orionis-0.643.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
410
|
+
orionis-0.643.0.dist-info/top_level.txt,sha256=lyXi6jArpqJ-0zzNqd_uwsH-z9TCEBVBL-pC3Ekv7hU,8
|
|
411
|
+
orionis-0.643.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|