orionis 0.404.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.
- orionis/console/base/command.py +57 -50
- orionis/console/base/contracts/command.py +68 -0
- orionis/console/dynamic/contracts/progress_bar.py +3 -3
- orionis/console/dynamic/progress_bar.py +8 -8
- orionis/console/output/console.py +8 -2
- orionis/console/output/contracts/console.py +1 -1
- orionis/container/container.py +2 -2
- orionis/container/context/scope.py +4 -1
- orionis/container/contracts/service_provider.py +2 -2
- orionis/container/entities/binding.py +31 -44
- orionis/container/enums/lifetimes.py +22 -1
- orionis/container/facades/facade.py +1 -2
- orionis/container/providers/service_provider.py +2 -2
- orionis/foundation/application.py +542 -248
- orionis/foundation/config/app/entities/app.py +107 -90
- orionis/foundation/config/auth/entities/auth.py +4 -33
- orionis/foundation/config/cache/entities/cache.py +18 -41
- orionis/foundation/config/cache/entities/file.py +8 -35
- orionis/foundation/config/cache/entities/stores.py +17 -38
- orionis/foundation/config/cors/entities/cors.py +41 -54
- orionis/foundation/config/database/entities/connections.py +40 -56
- orionis/foundation/config/database/entities/database.py +11 -38
- orionis/foundation/config/database/entities/mysql.py +48 -76
- orionis/foundation/config/database/entities/oracle.py +30 -57
- orionis/foundation/config/database/entities/pgsql.py +45 -61
- orionis/foundation/config/database/entities/sqlite.py +26 -53
- orionis/foundation/config/filesystems/entitites/aws.py +28 -49
- orionis/foundation/config/filesystems/entitites/disks.py +27 -47
- orionis/foundation/config/filesystems/entitites/filesystems.py +15 -37
- orionis/foundation/config/filesystems/entitites/local.py +9 -35
- orionis/foundation/config/filesystems/entitites/public.py +14 -41
- orionis/foundation/config/logging/entities/channels.py +56 -86
- orionis/foundation/config/logging/entities/chunked.py +18 -10
- orionis/foundation/config/logging/entities/daily.py +17 -9
- orionis/foundation/config/logging/entities/hourly.py +15 -7
- orionis/foundation/config/logging/entities/logging.py +12 -18
- orionis/foundation/config/logging/entities/monthly.py +16 -8
- orionis/foundation/config/logging/entities/stack.py +15 -7
- orionis/foundation/config/logging/entities/weekly.py +15 -7
- orionis/foundation/config/logging/validators/path.py +6 -0
- orionis/foundation/config/mail/entities/file.py +9 -36
- orionis/foundation/config/mail/entities/mail.py +22 -40
- orionis/foundation/config/mail/entities/mailers.py +29 -44
- orionis/foundation/config/mail/entities/smtp.py +47 -48
- orionis/foundation/config/queue/entities/brokers.py +19 -41
- orionis/foundation/config/queue/entities/database.py +24 -46
- orionis/foundation/config/queue/entities/queue.py +28 -40
- orionis/foundation/config/roots/paths.py +272 -468
- orionis/foundation/config/session/entities/session.py +23 -53
- orionis/foundation/config/startup.py +165 -135
- orionis/foundation/config/testing/entities/testing.py +137 -122
- orionis/foundation/config/testing/enums/__init__.py +6 -2
- orionis/foundation/config/testing/enums/drivers.py +16 -0
- orionis/foundation/config/testing/enums/verbosity.py +18 -0
- orionis/foundation/contracts/application.py +152 -362
- orionis/foundation/providers/console_provider.py +24 -2
- orionis/foundation/providers/dumper_provider.py +24 -2
- orionis/foundation/providers/logger_provider.py +24 -2
- orionis/foundation/providers/path_resolver_provider.py +25 -2
- orionis/foundation/providers/progress_bar_provider.py +24 -2
- orionis/foundation/providers/testing_provider.py +39 -0
- orionis/foundation/providers/workers_provider.py +24 -2
- orionis/metadata/framework.py +1 -1
- orionis/services/environment/helpers/functions.py +1 -2
- orionis/services/environment/key/__init__.py +0 -0
- orionis/services/environment/key/key_generator.py +37 -0
- orionis/services/log/handlers/filename.py +64 -0
- orionis/services/log/handlers/size_rotating.py +9 -40
- orionis/services/log/handlers/timed_rotating.py +9 -41
- orionis/services/log/log_service.py +9 -52
- orionis/support/entities/__init__.py +0 -0
- orionis/support/entities/base.py +104 -0
- orionis/support/facades/testing.py +15 -0
- orionis/support/facades/workers.py +1 -1
- orionis/test/cases/asynchronous.py +0 -11
- orionis/test/cases/synchronous.py +0 -9
- orionis/test/contracts/dumper.py +11 -4
- orionis/test/contracts/kernel.py +5 -110
- orionis/test/contracts/logs.py +27 -65
- orionis/test/contracts/printer.py +16 -128
- orionis/test/contracts/test_result.py +100 -0
- orionis/test/contracts/unit_test.py +87 -150
- orionis/test/core/unit_test.py +608 -554
- orionis/test/entities/result.py +22 -2
- orionis/test/enums/__init__.py +0 -2
- orionis/test/enums/status.py +14 -9
- orionis/test/exceptions/config.py +9 -1
- orionis/test/exceptions/failure.py +34 -11
- orionis/test/exceptions/persistence.py +10 -2
- orionis/test/exceptions/runtime.py +9 -1
- orionis/test/exceptions/value.py +13 -1
- orionis/test/kernel.py +87 -289
- orionis/test/output/dumper.py +82 -18
- orionis/test/output/printer.py +399 -156
- orionis/test/records/logs.py +203 -82
- orionis/test/validators/__init__.py +33 -0
- orionis/test/validators/base_path.py +45 -0
- orionis/test/validators/execution_mode.py +45 -0
- orionis/test/validators/fail_fast.py +37 -0
- orionis/test/validators/folder_path.py +34 -0
- orionis/test/validators/module_name.py +31 -0
- orionis/test/validators/name_pattern.py +40 -0
- orionis/test/validators/pattern.py +36 -0
- orionis/test/validators/persistent.py +42 -0
- orionis/test/validators/persistent_driver.py +43 -0
- orionis/test/validators/print_result.py +37 -0
- orionis/test/validators/tags.py +37 -0
- orionis/test/validators/throw_exception.py +39 -0
- orionis/test/validators/verbosity.py +37 -0
- orionis/test/validators/web_report.py +35 -0
- orionis/test/validators/workers.py +31 -0
- orionis/test/view/render.py +48 -54
- {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/METADATA +1 -1
- {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/RECORD +160 -108
- tests/container/__init__.py +0 -0
- tests/container/context/__init__.py +0 -0
- tests/container/context/test_manager.py +27 -0
- tests/container/context/test_scope.py +23 -0
- tests/container/entities/__init__.py +0 -0
- tests/container/entities/test_binding.py +133 -0
- tests/container/enums/__init__.py +0 -0
- tests/container/enums/test_lifetimes.py +63 -0
- tests/container/facades/__init__.py +0 -0
- tests/container/facades/test_facade.py +61 -0
- tests/container/mocks/__init__.py +0 -0
- tests/container/mocks/mock_complex_classes.py +482 -0
- tests/container/mocks/mock_simple_classes.py +32 -0
- tests/container/providers/__init__.py +0 -0
- tests/container/providers/test_providers.py +48 -0
- tests/container/resolver/__init__.py +0 -0
- tests/container/resolver/test_resolver.py +55 -0
- tests/container/test_container.py +254 -0
- tests/container/test_singleton.py +98 -0
- tests/container/test_thread_safety.py +217 -0
- tests/container/validators/__init__.py +0 -0
- tests/container/validators/test_implements.py +140 -0
- tests/container/validators/test_is_abstract_class.py +99 -0
- tests/container/validators/test_is_callable.py +73 -0
- tests/container/validators/test_is_concrete_class.py +97 -0
- tests/container/validators/test_is_instance.py +105 -0
- tests/container/validators/test_is_not_subclass.py +117 -0
- tests/container/validators/test_is_subclass.py +115 -0
- tests/container/validators/test_is_valid_alias.py +113 -0
- tests/container/validators/test_lifetime.py +75 -0
- tests/foundation/config/logging/test_foundation_config_logging_chunked.py +12 -34
- tests/foundation/config/logging/test_foundation_config_logging_daily.py +11 -11
- tests/foundation/config/logging/test_foundation_config_logging_hourly.py +7 -8
- tests/foundation/config/logging/test_foundation_config_logging_monthly.py +7 -10
- tests/foundation/config/logging/test_foundation_config_logging_stack.py +6 -11
- tests/foundation/config/logging/test_foundation_config_logging_weekly.py +6 -5
- tests/foundation/config/testing/test_foundation_config_testing.py +1 -1
- tests/metadata/test_metadata_framework.py +18 -18
- tests/testing/test_testing_result.py +117 -117
- tests/testing/test_testing_unit.py +209 -209
- orionis/foundation/config/base.py +0 -112
- orionis/test/arguments/parser.py +0 -187
- orionis/test/contracts/parser.py +0 -43
- orionis/test/entities/arguments.py +0 -38
- orionis/test/enums/execution_mode.py +0 -16
- /orionis/{test/arguments → console/base/contracts}/__init__.py +0 -0
- /orionis/foundation/config/testing/enums/{test_mode.py → mode.py} +0 -0
- {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/WHEEL +0 -0
- {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/top_level.txt +0 -0
- {orionis-0.404.0.dist-info → orionis-0.406.0.dist-info}/zip-safe +0 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
from abc import ABC
|
|
2
|
+
from orionis.container.validators.is_subclass import IsSubclass
|
|
3
|
+
from orionis.container.exceptions.exception import OrionisContainerException
|
|
4
|
+
from orionis.test.cases.asynchronous import AsyncTestCase
|
|
5
|
+
|
|
6
|
+
class TestIsSubclass(AsyncTestCase):
|
|
7
|
+
"""
|
|
8
|
+
Test cases for the IsSubclass validator in orionis.container.validators.is_subclass.
|
|
9
|
+
|
|
10
|
+
Notes
|
|
11
|
+
-----
|
|
12
|
+
This test suite validates the functionality of the IsSubclass validator
|
|
13
|
+
which ensures that a concrete class is a subclass of an abstract class.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
async def testValidSubclass(self) -> None:
|
|
17
|
+
"""
|
|
18
|
+
Test that validation passes when concrete class is a valid subclass.
|
|
19
|
+
"""
|
|
20
|
+
# Define test classes
|
|
21
|
+
class AbstractClass(ABC):
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
class ConcreteClass(AbstractClass):
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
class SubConcreteClass(ConcreteClass):
|
|
28
|
+
pass
|
|
29
|
+
|
|
30
|
+
# These should not raise exceptions
|
|
31
|
+
IsSubclass(AbstractClass, ConcreteClass)
|
|
32
|
+
IsSubclass(AbstractClass, SubConcreteClass)
|
|
33
|
+
IsSubclass(ConcreteClass, SubConcreteClass)
|
|
34
|
+
|
|
35
|
+
async def testInvalidSubclass(self) -> None:
|
|
36
|
+
"""
|
|
37
|
+
Test that validation fails when concrete class is not a subclass.
|
|
38
|
+
"""
|
|
39
|
+
# Define test classes
|
|
40
|
+
class AbstractClass1(ABC):
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
class AbstractClass2(ABC):
|
|
44
|
+
pass
|
|
45
|
+
|
|
46
|
+
class ConcreteClass1(AbstractClass1):
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
class ConcreteClass2(AbstractClass2):
|
|
50
|
+
pass
|
|
51
|
+
|
|
52
|
+
# These should raise exceptions
|
|
53
|
+
with self.assertRaises(OrionisContainerException) as context:
|
|
54
|
+
IsSubclass(AbstractClass1, AbstractClass2)
|
|
55
|
+
self.assertIn("concrete class must inherit", str(context.exception))
|
|
56
|
+
|
|
57
|
+
with self.assertRaises(OrionisContainerException) as context:
|
|
58
|
+
IsSubclass(AbstractClass1, ConcreteClass2)
|
|
59
|
+
self.assertIn("concrete class must inherit", str(context.exception))
|
|
60
|
+
|
|
61
|
+
with self.assertRaises(OrionisContainerException) as context:
|
|
62
|
+
IsSubclass(ConcreteClass1, AbstractClass1)
|
|
63
|
+
self.assertIn("concrete class must inherit", str(context.exception))
|
|
64
|
+
|
|
65
|
+
async def testSameClass(self) -> None:
|
|
66
|
+
"""
|
|
67
|
+
Test validation when abstract and concrete are the same class.
|
|
68
|
+
"""
|
|
69
|
+
class TestClass:
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
# A class is considered a subclass of itself
|
|
73
|
+
IsSubclass(TestClass, TestClass)
|
|
74
|
+
|
|
75
|
+
async def testBuiltinTypes(self) -> None:
|
|
76
|
+
"""
|
|
77
|
+
Test validation with built-in types.
|
|
78
|
+
"""
|
|
79
|
+
# Valid subclass relationships
|
|
80
|
+
IsSubclass(Exception, ValueError)
|
|
81
|
+
IsSubclass(BaseException, Exception)
|
|
82
|
+
|
|
83
|
+
# Invalid subclass relationships
|
|
84
|
+
with self.assertRaises(OrionisContainerException):
|
|
85
|
+
IsSubclass(ValueError, Exception)
|
|
86
|
+
|
|
87
|
+
with self.assertRaises(OrionisContainerException):
|
|
88
|
+
IsSubclass(int, str)
|
|
89
|
+
|
|
90
|
+
with self.assertRaises(OrionisContainerException):
|
|
91
|
+
IsSubclass(list, dict)
|
|
92
|
+
|
|
93
|
+
async def testNonClassArguments(self) -> None:
|
|
94
|
+
"""
|
|
95
|
+
Test validation with non-class arguments which should raise TypeError.
|
|
96
|
+
"""
|
|
97
|
+
class TestClass:
|
|
98
|
+
pass
|
|
99
|
+
|
|
100
|
+
# These should raise TypeError when passed to issubclass()
|
|
101
|
+
non_class_args = [
|
|
102
|
+
None,
|
|
103
|
+
123,
|
|
104
|
+
"string",
|
|
105
|
+
[],
|
|
106
|
+
{},
|
|
107
|
+
lambda x: x
|
|
108
|
+
]
|
|
109
|
+
|
|
110
|
+
for arg in non_class_args:
|
|
111
|
+
with self.assertRaises(TypeError):
|
|
112
|
+
IsSubclass(TestClass, arg)
|
|
113
|
+
|
|
114
|
+
with self.assertRaises(TypeError):
|
|
115
|
+
IsSubclass(arg, TestClass)
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
from orionis.container.validators.is_valid_alias import IsValidAlias
|
|
2
|
+
from orionis.container.exceptions.type import OrionisContainerTypeError
|
|
3
|
+
from orionis.test.cases.asynchronous import AsyncTestCase
|
|
4
|
+
|
|
5
|
+
class TestIsValidAlias(AsyncTestCase):
|
|
6
|
+
"""
|
|
7
|
+
Test cases for the IsValidAlias validator in orionis.container.validators.is_valid_alias.
|
|
8
|
+
|
|
9
|
+
Notes
|
|
10
|
+
-----
|
|
11
|
+
This test suite validates the functionality of the IsValidAlias validator
|
|
12
|
+
which ensures that alias values are valid strings without invalid characters.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
async def testValidAliases(self) -> None:
|
|
16
|
+
"""
|
|
17
|
+
Test that validation passes when valid aliases are provided.
|
|
18
|
+
"""
|
|
19
|
+
valid_aliases = [
|
|
20
|
+
"valid",
|
|
21
|
+
"valid_alias",
|
|
22
|
+
"validAlias",
|
|
23
|
+
"valid123",
|
|
24
|
+
"valid_123",
|
|
25
|
+
"v",
|
|
26
|
+
"1",
|
|
27
|
+
"_",
|
|
28
|
+
"valid_alias_with_underscores",
|
|
29
|
+
"ValidAliasWithMixedCase",
|
|
30
|
+
"VALID_UPPERCASE_ALIAS"
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
for alias in valid_aliases:
|
|
34
|
+
IsValidAlias(alias)
|
|
35
|
+
|
|
36
|
+
async def testInvalidAliasTypes(self) -> None:
|
|
37
|
+
"""
|
|
38
|
+
Test that validation fails when non-string types are provided.
|
|
39
|
+
"""
|
|
40
|
+
invalid_types = [
|
|
41
|
+
123,
|
|
42
|
+
3.14,
|
|
43
|
+
None,
|
|
44
|
+
True,
|
|
45
|
+
False,
|
|
46
|
+
[],
|
|
47
|
+
{},
|
|
48
|
+
(),
|
|
49
|
+
set()
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
for value in invalid_types:
|
|
53
|
+
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
54
|
+
IsValidAlias(value)
|
|
55
|
+
|
|
56
|
+
async def testAliasWithInvalidCharacters(self) -> None:
|
|
57
|
+
"""
|
|
58
|
+
Test that validation fails when aliases contain invalid characters.
|
|
59
|
+
"""
|
|
60
|
+
invalid_aliases = [
|
|
61
|
+
"invalid alias", # space
|
|
62
|
+
"invalid\talias", # tab
|
|
63
|
+
"invalid\nalias", # newline
|
|
64
|
+
"invalid@alias", # special character
|
|
65
|
+
"invalid#alias", # special character
|
|
66
|
+
"invalid$alias", # special character
|
|
67
|
+
"invalid%alias", # special character
|
|
68
|
+
"invalid&alias", # special character
|
|
69
|
+
"invalid*alias", # special character
|
|
70
|
+
"invalid(alias)", # parentheses
|
|
71
|
+
"invalid[alias]", # brackets
|
|
72
|
+
"invalid{alias}", # braces
|
|
73
|
+
"invalid;alias", # semicolon
|
|
74
|
+
"invalid:alias", # colon
|
|
75
|
+
"invalid,alias", # comma
|
|
76
|
+
"invalid/alias", # slash
|
|
77
|
+
"invalid\\alias", # backslash
|
|
78
|
+
"invalid<alias>", # angle brackets
|
|
79
|
+
"invalid|alias", # pipe
|
|
80
|
+
"invalid`alias", # backtick
|
|
81
|
+
'invalid"alias', # double quote
|
|
82
|
+
"invalid'alias" # single quote
|
|
83
|
+
]
|
|
84
|
+
|
|
85
|
+
for alias in invalid_aliases:
|
|
86
|
+
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
87
|
+
IsValidAlias(alias)
|
|
88
|
+
|
|
89
|
+
expected_msg_start = f"Alias '{alias}' contains invalid characters."
|
|
90
|
+
self.assertTrue(str(context.exception).startswith(expected_msg_start))
|
|
91
|
+
self.assertIn("Aliases must not contain whitespace or special symbols", str(context.exception))
|
|
92
|
+
|
|
93
|
+
async def testEmptyAlias(self) -> None:
|
|
94
|
+
"""
|
|
95
|
+
Test that validation fails with an empty string.
|
|
96
|
+
"""
|
|
97
|
+
# Empty string should be rejected
|
|
98
|
+
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
99
|
+
IsValidAlias("")
|
|
100
|
+
|
|
101
|
+
self.assertEqual(
|
|
102
|
+
str(context.exception),
|
|
103
|
+
"Alias cannot be None, empty, or whitespace only."
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
# Whitespace-only string should also be rejected
|
|
107
|
+
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
108
|
+
IsValidAlias(" ")
|
|
109
|
+
|
|
110
|
+
self.assertEqual(
|
|
111
|
+
str(context.exception),
|
|
112
|
+
"Alias cannot be None, empty, or whitespace only."
|
|
113
|
+
)
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
from orionis.container.validators.lifetime import LifetimeValidator
|
|
2
|
+
from orionis.container.enums.lifetimes import Lifetime
|
|
3
|
+
from orionis.container.exceptions.type import OrionisContainerTypeError
|
|
4
|
+
from orionis.test.cases.asynchronous import AsyncTestCase
|
|
5
|
+
|
|
6
|
+
class TestLifetimeValidator(AsyncTestCase):
|
|
7
|
+
"""
|
|
8
|
+
Test cases for the LifetimeValidator in orionis.container.validators.lifetime.
|
|
9
|
+
|
|
10
|
+
Notes
|
|
11
|
+
-----
|
|
12
|
+
This test suite validates the functionality of the LifetimeValidator
|
|
13
|
+
which ensures that lifetime values are correctly validated and converted.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
async def testValidLifetimeEnumValues(self) -> None:
|
|
17
|
+
"""
|
|
18
|
+
Test that validation passes when Lifetime enum values are provided.
|
|
19
|
+
"""
|
|
20
|
+
self.assertEqual(LifetimeValidator(Lifetime.TRANSIENT), Lifetime.TRANSIENT)
|
|
21
|
+
self.assertEqual(LifetimeValidator(Lifetime.SINGLETON), Lifetime.SINGLETON)
|
|
22
|
+
self.assertEqual(LifetimeValidator(Lifetime.SCOPED), Lifetime.SCOPED)
|
|
23
|
+
|
|
24
|
+
async def testValidLifetimeStringValues(self) -> None:
|
|
25
|
+
"""
|
|
26
|
+
Test that validation passes when valid string representations are provided.
|
|
27
|
+
"""
|
|
28
|
+
self.assertEqual(LifetimeValidator("TRANSIENT"), Lifetime.TRANSIENT)
|
|
29
|
+
self.assertEqual(LifetimeValidator("SINGLETON"), Lifetime.SINGLETON)
|
|
30
|
+
self.assertEqual(LifetimeValidator("SCOPED"), Lifetime.SCOPED)
|
|
31
|
+
|
|
32
|
+
# Test with lowercase and mixed case
|
|
33
|
+
self.assertEqual(LifetimeValidator("transient"), Lifetime.TRANSIENT)
|
|
34
|
+
self.assertEqual(LifetimeValidator("Singleton"), Lifetime.SINGLETON)
|
|
35
|
+
self.assertEqual(LifetimeValidator("scoped"), Lifetime.SCOPED)
|
|
36
|
+
|
|
37
|
+
# Test with extra whitespace
|
|
38
|
+
self.assertEqual(LifetimeValidator(" TRANSIENT "), Lifetime.TRANSIENT)
|
|
39
|
+
self.assertEqual(LifetimeValidator(" singleton "), Lifetime.SINGLETON)
|
|
40
|
+
|
|
41
|
+
async def testInvalidLifetimeStringValue(self) -> None:
|
|
42
|
+
"""
|
|
43
|
+
Test that validation fails when invalid string representations are provided.
|
|
44
|
+
"""
|
|
45
|
+
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
46
|
+
LifetimeValidator("INVALID_LIFETIME")
|
|
47
|
+
|
|
48
|
+
self.assertIn("Invalid lifetime 'INVALID_LIFETIME'", str(context.exception))
|
|
49
|
+
self.assertIn("Valid options are:", str(context.exception))
|
|
50
|
+
self.assertIn("TRANSIENT", str(context.exception))
|
|
51
|
+
self.assertIn("SINGLETON", str(context.exception))
|
|
52
|
+
self.assertIn("SCOPED", str(context.exception))
|
|
53
|
+
|
|
54
|
+
async def testInvalidLifetimeType(self) -> None:
|
|
55
|
+
"""
|
|
56
|
+
Test that validation fails when invalid types are provided.
|
|
57
|
+
"""
|
|
58
|
+
invalid_values = [
|
|
59
|
+
123,
|
|
60
|
+
3.14,
|
|
61
|
+
None,
|
|
62
|
+
True,
|
|
63
|
+
False,
|
|
64
|
+
[],
|
|
65
|
+
{},
|
|
66
|
+
(),
|
|
67
|
+
set()
|
|
68
|
+
]
|
|
69
|
+
|
|
70
|
+
for value in invalid_values:
|
|
71
|
+
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
72
|
+
LifetimeValidator(value)
|
|
73
|
+
|
|
74
|
+
expected_msg = f"Lifetime must be of type str or Lifetime enum, got {type(value).__name__}."
|
|
75
|
+
self.assertEqual(str(context.exception), expected_msg)
|
|
@@ -25,7 +25,7 @@ class TestFoundationConfigLoggingChunked(AsyncTestCase):
|
|
|
25
25
|
None
|
|
26
26
|
"""
|
|
27
27
|
chunked = Chunked()
|
|
28
|
-
self.assertEqual(chunked.path, "storage/log/
|
|
28
|
+
self.assertEqual(chunked.path, "storage/log/chunked.log")
|
|
29
29
|
self.assertEqual(chunked.level, Level.INFO.value)
|
|
30
30
|
self.assertEqual(chunked.mb_size, 10)
|
|
31
31
|
self.assertEqual(chunked.files, 5)
|
|
@@ -85,39 +85,19 @@ class TestFoundationConfigLoggingChunked(AsyncTestCase):
|
|
|
85
85
|
"""
|
|
86
86
|
Test validation of the `mb_size` attribute.
|
|
87
87
|
|
|
88
|
-
Ensures that valid integer and string formats are accepted, and invalid
|
|
89
|
-
values raise `OrionisIntegrityException`.
|
|
90
|
-
|
|
91
88
|
Returns
|
|
92
89
|
-------
|
|
93
90
|
None
|
|
94
91
|
"""
|
|
95
|
-
|
|
96
|
-
try:
|
|
97
|
-
Chunked(mb_size=1)
|
|
98
|
-
Chunked(mb_size=100)
|
|
99
|
-
except OrionisIntegrityException:
|
|
100
|
-
self.fail("Valid mb_size should not raise exception")
|
|
101
|
-
|
|
102
|
-
# Test string formats
|
|
103
|
-
chunked = Chunked(mb_size="10MB")
|
|
92
|
+
chunked = Chunked(mb_size=10)
|
|
104
93
|
self.assertEqual(chunked.mb_size, 10)
|
|
105
94
|
|
|
106
|
-
chunked = Chunked(mb_size=
|
|
107
|
-
self.assertEqual(chunked.mb_size,
|
|
108
|
-
|
|
109
|
-
chunked = Chunked(mb_size="10485760B")
|
|
110
|
-
self.assertEqual(chunked.mb_size, 10)
|
|
95
|
+
chunked = Chunked(mb_size=1000)
|
|
96
|
+
self.assertEqual(chunked.mb_size, 1000)
|
|
111
97
|
|
|
112
|
-
# Test invalid cases
|
|
113
|
-
with self.assertRaises(OrionisIntegrityException):
|
|
114
|
-
Chunked(mb_size=0)
|
|
115
|
-
with self.assertRaises(OrionisIntegrityException):
|
|
116
|
-
Chunked(mb_size=-1)
|
|
117
|
-
with self.assertRaises(OrionisIntegrityException):
|
|
118
|
-
Chunked(mb_size="invalid")
|
|
119
98
|
with self.assertRaises(OrionisIntegrityException):
|
|
120
|
-
Chunked(mb_size=
|
|
99
|
+
chunked = Chunked(mb_size=2048)
|
|
100
|
+
self.assertEqual(chunked.mb_size, 2048)
|
|
121
101
|
|
|
122
102
|
async def testFilesValidation(self):
|
|
123
103
|
"""
|
|
@@ -149,16 +129,14 @@ class TestFoundationConfigLoggingChunked(AsyncTestCase):
|
|
|
149
129
|
"""
|
|
150
130
|
Test handling of whitespace in `path` and `level` attributes.
|
|
151
131
|
|
|
152
|
-
Ensures that leading and trailing whitespace in `path` and `level` are
|
|
153
|
-
handled as expected.
|
|
154
|
-
|
|
155
132
|
Returns
|
|
156
133
|
-------
|
|
157
134
|
None
|
|
158
135
|
"""
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
136
|
+
with self.assertRaises(OrionisIntegrityException):
|
|
137
|
+
chunked = Chunked(path=" logs/app.log ", level=" debug ")
|
|
138
|
+
self.assertEqual(chunked.path, " logs/app.log ")
|
|
139
|
+
self.assertEqual(chunked.level, Level.DEBUG.value)
|
|
162
140
|
|
|
163
141
|
async def testToDictMethod(self):
|
|
164
142
|
"""
|
|
@@ -175,7 +153,7 @@ class TestFoundationConfigLoggingChunked(AsyncTestCase):
|
|
|
175
153
|
chunked_dict = chunked.toDict()
|
|
176
154
|
|
|
177
155
|
self.assertIsInstance(chunked_dict, dict)
|
|
178
|
-
self.assertEqual(chunked_dict['path'], "storage/log/
|
|
156
|
+
self.assertEqual(chunked_dict['path'], "storage/log/chunked.log")
|
|
179
157
|
self.assertEqual(chunked_dict['level'], Level.INFO.value)
|
|
180
158
|
self.assertEqual(chunked_dict['mb_size'], 10)
|
|
181
159
|
self.assertEqual(chunked_dict['files'], 5)
|
|
@@ -199,7 +177,7 @@ class TestFoundationConfigLoggingChunked(AsyncTestCase):
|
|
|
199
177
|
)
|
|
200
178
|
chunked_dict = custom_chunked.toDict()
|
|
201
179
|
self.assertEqual(chunked_dict['path'], "custom/logs/app.log")
|
|
202
|
-
self.assertEqual(chunked_dict['level'],
|
|
180
|
+
self.assertEqual(chunked_dict['level'], 30)
|
|
203
181
|
self.assertEqual(chunked_dict['mb_size'], 20)
|
|
204
182
|
self.assertEqual(chunked_dict['files'], 10)
|
|
205
183
|
|
|
@@ -25,10 +25,10 @@ class TestFoundationConfigLoggingDaily(AsyncTestCase):
|
|
|
25
25
|
None
|
|
26
26
|
"""
|
|
27
27
|
daily = Daily()
|
|
28
|
-
self.assertEqual(daily.path, "storage/log/
|
|
28
|
+
self.assertEqual(daily.path, "storage/log/daily.log")
|
|
29
29
|
self.assertEqual(daily.level, Level.INFO.value)
|
|
30
30
|
self.assertEqual(daily.retention_days, 7)
|
|
31
|
-
self.assertEqual(daily.at, "00:00
|
|
31
|
+
self.assertEqual(daily.at, "00:00")
|
|
32
32
|
|
|
33
33
|
async def testPathValidation(self):
|
|
34
34
|
"""
|
|
@@ -122,7 +122,7 @@ class TestFoundationConfigLoggingDaily(AsyncTestCase):
|
|
|
122
122
|
"""
|
|
123
123
|
# Test time object
|
|
124
124
|
daily = Daily(at=time(12, 30))
|
|
125
|
-
self.assertEqual(daily.at, "12:30
|
|
125
|
+
self.assertEqual(daily.at, "12:30")
|
|
126
126
|
|
|
127
127
|
# Test invalid type
|
|
128
128
|
with self.assertRaises(OrionisIntegrityException):
|
|
@@ -134,15 +134,15 @@ class TestFoundationConfigLoggingDaily(AsyncTestCase):
|
|
|
134
134
|
"""
|
|
135
135
|
Test handling of whitespace in path and level attributes.
|
|
136
136
|
|
|
137
|
-
Ensures that whitespace in path and level is preserved or handled as expected.
|
|
138
|
-
|
|
139
137
|
Returns
|
|
140
138
|
-------
|
|
141
139
|
None
|
|
142
140
|
"""
|
|
143
|
-
|
|
144
|
-
self.
|
|
145
|
-
|
|
141
|
+
|
|
142
|
+
with self.assertRaises(OrionisIntegrityException):
|
|
143
|
+
daily = Daily(path=" logs/app.log ", level=" debug ")
|
|
144
|
+
self.assertEqual(daily.path, " logs/app.log ")
|
|
145
|
+
self.assertEqual(daily.level, Level.DEBUG.value)
|
|
146
146
|
|
|
147
147
|
async def testToDictMethod(self):
|
|
148
148
|
"""
|
|
@@ -159,10 +159,10 @@ class TestFoundationConfigLoggingDaily(AsyncTestCase):
|
|
|
159
159
|
daily_dict = daily.toDict()
|
|
160
160
|
|
|
161
161
|
self.assertIsInstance(daily_dict, dict)
|
|
162
|
-
self.assertEqual(daily_dict['path'], "storage/log/
|
|
162
|
+
self.assertEqual(daily_dict['path'], "storage/log/daily.log")
|
|
163
163
|
self.assertEqual(daily_dict['level'], Level.INFO.value)
|
|
164
164
|
self.assertEqual(daily_dict['retention_days'], 7)
|
|
165
|
-
self.assertEqual(daily_dict['at'], "00:00
|
|
165
|
+
self.assertEqual(daily_dict['at'], "00:00")
|
|
166
166
|
|
|
167
167
|
async def testCustomValuesToDict(self):
|
|
168
168
|
"""
|
|
@@ -184,7 +184,7 @@ class TestFoundationConfigLoggingDaily(AsyncTestCase):
|
|
|
184
184
|
self.assertEqual(daily_dict['path'], "custom/logs/app.log")
|
|
185
185
|
self.assertEqual(daily_dict['level'], Level.WARNING.value)
|
|
186
186
|
self.assertEqual(daily_dict['retention_days'], 14)
|
|
187
|
-
self.assertEqual(daily_dict['at'], "23:59
|
|
187
|
+
self.assertEqual(daily_dict['at'], "23:59")
|
|
188
188
|
|
|
189
189
|
async def testHashability(self):
|
|
190
190
|
"""
|
|
@@ -24,7 +24,7 @@ class TestFoundationConfigLoggingHourly(AsyncTestCase):
|
|
|
24
24
|
None
|
|
25
25
|
"""
|
|
26
26
|
hourly = Hourly()
|
|
27
|
-
self.assertEqual(hourly.path, "storage/log/
|
|
27
|
+
self.assertEqual(hourly.path, "storage/log/hourly.log")
|
|
28
28
|
self.assertEqual(hourly.level, Level.INFO.value)
|
|
29
29
|
self.assertEqual(hourly.retention_hours, 24)
|
|
30
30
|
|
|
@@ -113,16 +113,15 @@ class TestFoundationConfigLoggingHourly(AsyncTestCase):
|
|
|
113
113
|
"""
|
|
114
114
|
Test whitespace handling in path and level attributes.
|
|
115
115
|
|
|
116
|
-
Verifies that leading and trailing whitespace in the `path` and `level`
|
|
117
|
-
attributes are handled as expected.
|
|
118
|
-
|
|
119
116
|
Returns
|
|
120
117
|
-------
|
|
121
118
|
None
|
|
122
119
|
"""
|
|
123
|
-
|
|
124
|
-
self.
|
|
125
|
-
|
|
120
|
+
|
|
121
|
+
with self.assertRaises(OrionisIntegrityException):
|
|
122
|
+
hourly = Hourly(path=" logs/app.log ", level=" debug ")
|
|
123
|
+
self.assertEqual(hourly.path, " logs/app.log ")
|
|
124
|
+
self.assertEqual(hourly.level, Level.DEBUG.value)
|
|
126
125
|
|
|
127
126
|
async def testToDictMethod(self):
|
|
128
127
|
"""
|
|
@@ -138,7 +137,7 @@ class TestFoundationConfigLoggingHourly(AsyncTestCase):
|
|
|
138
137
|
hourly = Hourly()
|
|
139
138
|
hourly_dict = hourly.toDict()
|
|
140
139
|
self.assertIsInstance(hourly_dict, dict)
|
|
141
|
-
self.assertEqual(hourly_dict['path'], "storage/log/
|
|
140
|
+
self.assertEqual(hourly_dict['path'], "storage/log/hourly.log")
|
|
142
141
|
self.assertEqual(hourly_dict['level'], Level.INFO.value)
|
|
143
142
|
self.assertEqual(hourly_dict['retention_hours'], 24)
|
|
144
143
|
|
|
@@ -25,7 +25,7 @@ class TestFoundationConfigLoggingMonthly(AsyncTestCase):
|
|
|
25
25
|
- Default retention_months is 4.
|
|
26
26
|
"""
|
|
27
27
|
monthly = Monthly()
|
|
28
|
-
self.assertEqual(monthly.path, "storage/log/
|
|
28
|
+
self.assertEqual(monthly.path, "storage/log/monthly.log")
|
|
29
29
|
self.assertEqual(monthly.level, Level.INFO.value)
|
|
30
30
|
self.assertEqual(monthly.retention_months, 4)
|
|
31
31
|
|
|
@@ -106,15 +106,12 @@ class TestFoundationConfigLoggingMonthly(AsyncTestCase):
|
|
|
106
106
|
async def testWhitespaceHandling(self):
|
|
107
107
|
"""
|
|
108
108
|
Test whitespace handling in path and level attributes.
|
|
109
|
-
|
|
110
|
-
Verifies
|
|
111
|
-
--------
|
|
112
|
-
- Whitespace in path is preserved.
|
|
113
|
-
- Whitespace in level is handled correctly.
|
|
114
109
|
"""
|
|
115
|
-
|
|
116
|
-
self.
|
|
117
|
-
|
|
110
|
+
|
|
111
|
+
with self.assertRaises(OrionisIntegrityException):
|
|
112
|
+
monthly = Monthly(path=" logs/app.log ", level=" debug ")
|
|
113
|
+
self.assertEqual(monthly.path, " logs/app.log ")
|
|
114
|
+
self.assertEqual(monthly.level, Level.DEBUG.value)
|
|
118
115
|
|
|
119
116
|
async def testToDictMethod(self):
|
|
120
117
|
"""
|
|
@@ -127,7 +124,7 @@ class TestFoundationConfigLoggingMonthly(AsyncTestCase):
|
|
|
127
124
|
monthly = Monthly()
|
|
128
125
|
monthly_dict = monthly.toDict()
|
|
129
126
|
self.assertIsInstance(monthly_dict, dict)
|
|
130
|
-
self.assertEqual(monthly_dict['path'], "storage/log/
|
|
127
|
+
self.assertEqual(monthly_dict['path'], "storage/log/monthly.log")
|
|
131
128
|
self.assertEqual(monthly_dict['level'], Level.INFO.value)
|
|
132
129
|
self.assertEqual(monthly_dict['retention_months'], 4)
|
|
133
130
|
|
|
@@ -20,7 +20,7 @@ class TestFoundationConfigLoggingStack(AsyncTestCase):
|
|
|
20
20
|
Verifies that the default path and level match the expected values from the class definition.
|
|
21
21
|
"""
|
|
22
22
|
stack = Stack()
|
|
23
|
-
self.assertEqual(stack.path, "storage/log/
|
|
23
|
+
self.assertEqual(stack.path, "storage/log/stack.log")
|
|
24
24
|
self.assertEqual(stack.level, Level.INFO.value)
|
|
25
25
|
|
|
26
26
|
async def testPathValidation(self):
|
|
@@ -84,17 +84,12 @@ class TestFoundationConfigLoggingStack(AsyncTestCase):
|
|
|
84
84
|
async def testWhitespaceHandling(self):
|
|
85
85
|
"""
|
|
86
86
|
Test handling of whitespace in path and level attributes.
|
|
87
|
-
|
|
88
|
-
Ensures that whitespace is preserved in the path and trimmed in level strings.
|
|
89
87
|
"""
|
|
90
|
-
# Test path with whitespace
|
|
91
|
-
spaced_path = " logs/app.log "
|
|
92
|
-
stack = Stack(path=spaced_path)
|
|
93
|
-
self.assertEqual(stack.path, spaced_path)
|
|
94
88
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
89
|
+
with self.assertRaises(OrionisIntegrityException):
|
|
90
|
+
spaced_path = " logs/app.log "
|
|
91
|
+
stack = Stack(path=spaced_path)
|
|
92
|
+
self.assertEqual(stack.path, spaced_path)
|
|
98
93
|
|
|
99
94
|
async def testToDictMethod(self):
|
|
100
95
|
"""
|
|
@@ -111,7 +106,7 @@ class TestFoundationConfigLoggingStack(AsyncTestCase):
|
|
|
111
106
|
stack_dict = stack.toDict()
|
|
112
107
|
|
|
113
108
|
self.assertIsInstance(stack_dict, dict)
|
|
114
|
-
self.assertEqual(stack_dict['path'], "storage/log/
|
|
109
|
+
self.assertEqual(stack_dict['path'], "storage/log/stack.log")
|
|
115
110
|
self.assertEqual(stack_dict['level'], Level.INFO.value)
|
|
116
111
|
|
|
117
112
|
async def testCustomValuesToDict(self):
|
|
@@ -49,7 +49,7 @@ class TestFoundationConfigLoggingWeekly(AsyncTestCase):
|
|
|
49
49
|
None
|
|
50
50
|
"""
|
|
51
51
|
weekly = Weekly()
|
|
52
|
-
self.assertEqual(weekly.path, "storage/log/
|
|
52
|
+
self.assertEqual(weekly.path, "storage/log/weekly.log")
|
|
53
53
|
self.assertEqual(weekly.level, Level.INFO.value)
|
|
54
54
|
self.assertEqual(weekly.retention_weeks, 4)
|
|
55
55
|
|
|
@@ -144,9 +144,10 @@ class TestFoundationConfigLoggingWeekly(AsyncTestCase):
|
|
|
144
144
|
-------
|
|
145
145
|
None
|
|
146
146
|
"""
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
147
|
+
with self.assertRaises(OrionisIntegrityException):
|
|
148
|
+
weekly = Weekly(path=" logs/app.log ", level=" debug ")
|
|
149
|
+
self.assertEqual(weekly.path, " logs/app.log ")
|
|
150
|
+
self.assertEqual(weekly.level, Level.DEBUG.value)
|
|
150
151
|
|
|
151
152
|
async def testToDictMethod(self):
|
|
152
153
|
"""
|
|
@@ -162,7 +163,7 @@ class TestFoundationConfigLoggingWeekly(AsyncTestCase):
|
|
|
162
163
|
weekly = Weekly()
|
|
163
164
|
weekly_dict = weekly.toDict()
|
|
164
165
|
self.assertIsInstance(weekly_dict, dict)
|
|
165
|
-
self.assertEqual(weekly_dict['path'], "storage/log/
|
|
166
|
+
self.assertEqual(weekly_dict['path'], "storage/log/weekly.log")
|
|
166
167
|
self.assertEqual(weekly_dict['level'], Level.INFO.value)
|
|
167
168
|
self.assertEqual(weekly_dict['retention_weeks'], 4)
|
|
168
169
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from orionis.foundation.config.testing.entities.testing import Testing
|
|
2
|
+
from orionis.foundation.config.testing.enums.mode import ExecutionMode
|
|
2
3
|
from orionis.foundation.exceptions import OrionisIntegrityException
|
|
3
|
-
from orionis.test.enums.execution_mode import ExecutionMode
|
|
4
4
|
from orionis.test.cases.asynchronous import AsyncTestCase
|
|
5
5
|
|
|
6
6
|
class TestFoundationConfigTesting(AsyncTestCase):
|