orionis 0.407.0__py3-none-any.whl → 0.409.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/container/container.py +11 -9
- orionis/container/enums/lifetimes.py +2 -0
- orionis/container/validators/__init__.py +21 -0
- orionis/metadata/framework.py +1 -1
- orionis/services/log/contracts/log_service.py +56 -4
- orionis/services/log/handlers/filename.py +20 -12
- orionis/services/log/handlers/size_rotating.py +11 -3
- orionis/services/log/handlers/timed_rotating.py +11 -3
- orionis/services/log/log_service.py +122 -72
- orionis/services/paths/contracts/resolver.py +0 -1
- {orionis-0.407.0.dist-info → orionis-0.409.0.dist-info}/METADATA +1 -1
- {orionis-0.407.0.dist-info → orionis-0.409.0.dist-info}/RECORD +37 -35
- tests/container/context/test_manager.py +15 -5
- tests/container/context/test_scope.py +12 -4
- tests/container/entities/test_binding.py +130 -21
- tests/container/enums/test_lifetimes.py +52 -18
- tests/container/facades/test_facade.py +29 -12
- tests/container/providers/test_providers.py +17 -10
- tests/container/resolver/test_resolver.py +14 -7
- tests/container/test_container.py +226 -71
- tests/container/test_singleton.py +43 -24
- tests/container/test_thread_safety.py +28 -156
- tests/container/validators/test_implements.py +59 -13
- tests/container/validators/test_is_abstract_class.py +73 -25
- tests/container/validators/test_is_callable.py +55 -26
- tests/container/validators/test_is_concrete_class.py +80 -17
- tests/container/validators/test_is_instance.py +67 -22
- tests/container/validators/test_is_not_subclass.py +28 -95
- tests/container/validators/test_is_subclass.py +84 -21
- tests/container/validators/test_is_valid_alias.py +46 -12
- tests/container/validators/test_lifetime.py +45 -14
- tests/services/log/__init__.py +0 -0
- tests/services/log/test_log.py +97 -0
- {orionis-0.407.0.dist-info → orionis-0.409.0.dist-info}/WHEEL +0 -0
- {orionis-0.407.0.dist-info → orionis-0.409.0.dist-info}/licenses/LICENCE +0 -0
- {orionis-0.407.0.dist-info → orionis-0.409.0.dist-info}/top_level.txt +0 -0
- {orionis-0.407.0.dist-info → orionis-0.409.0.dist-info}/zip-safe +0 -0
|
@@ -5,41 +5,54 @@ from orionis.container.exceptions.type import OrionisContainerTypeError
|
|
|
5
5
|
from orionis.test.cases.asynchronous import AsyncTestCase
|
|
6
6
|
|
|
7
7
|
class TestIsAbstractClass(AsyncTestCase):
|
|
8
|
-
"""
|
|
9
|
-
Test cases for the IsAbstractClass validator in orionis.container.validators.is_abstract_class.
|
|
10
|
-
|
|
11
|
-
Notes
|
|
12
|
-
-----
|
|
13
|
-
This test suite validates the functionality of the IsAbstractClass validator
|
|
14
|
-
which ensures that a provided class is an abstract class.
|
|
15
|
-
"""
|
|
16
8
|
|
|
17
9
|
async def testValidAbstractClass(self) -> None:
|
|
18
10
|
"""
|
|
19
|
-
|
|
11
|
+
Validates that the IsAbstractClass validator accepts a valid abstract class.
|
|
12
|
+
|
|
13
|
+
This test creates an abstract class using Python's `abc` module and verifies
|
|
14
|
+
that the validator does not raise an exception when provided with a proper abstract class.
|
|
15
|
+
|
|
16
|
+
Returns
|
|
17
|
+
-------
|
|
18
|
+
None
|
|
19
|
+
This method does not return anything. It asserts correct behavior via exceptions and mocks.
|
|
20
20
|
"""
|
|
21
|
-
# Create abstract class
|
|
21
|
+
# Create an abstract class with an abstract method
|
|
22
22
|
class AbstractBase(ABC):
|
|
23
23
|
@abstractmethod
|
|
24
24
|
def abstract_method(self):
|
|
25
25
|
pass
|
|
26
26
|
|
|
27
|
-
#
|
|
27
|
+
# Patch the reflection method to ensure it is called correctly
|
|
28
28
|
with unittest.mock.patch('orionis.services.introspection.abstract.reflection.ReflectionAbstract.ensureIsAbstractClass') as mock_ensure:
|
|
29
29
|
IsAbstractClass(AbstractBase, "singleton")
|
|
30
|
+
# Assert that the reflection method was called with the correct class
|
|
30
31
|
mock_ensure.assert_called_once_with(AbstractBase)
|
|
31
32
|
|
|
32
33
|
async def testNonAbstractClass(self) -> None:
|
|
33
34
|
"""
|
|
34
|
-
|
|
35
|
+
Validates that the IsAbstractClass validator raises an error for non-abstract classes.
|
|
36
|
+
|
|
37
|
+
This test provides a concrete class and mocks the reflection method to raise a ValueError,
|
|
38
|
+
ensuring that the validator responds with an OrionisContainerTypeError.
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
None
|
|
43
|
+
This method does not return anything. It asserts correct behavior via exceptions and mocks.
|
|
35
44
|
"""
|
|
45
|
+
# Define a concrete class with no abstract methods
|
|
36
46
|
class ConcreteClass:
|
|
37
47
|
def some_method(self):
|
|
38
48
|
pass
|
|
39
49
|
|
|
40
|
-
#
|
|
41
|
-
with unittest.mock.patch(
|
|
42
|
-
|
|
50
|
+
# Patch the reflection method to simulate failure for non-abstract classes
|
|
51
|
+
with unittest.mock.patch(
|
|
52
|
+
'orionis.services.introspection.abstract.reflection.ReflectionAbstract.ensureIsAbstractClass',
|
|
53
|
+
side_effect=ValueError("Not an abstract class")
|
|
54
|
+
) as mock_ensure:
|
|
55
|
+
# Assert that the validator raises the expected error
|
|
43
56
|
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
44
57
|
IsAbstractClass(ConcreteClass, "scoped")
|
|
45
58
|
|
|
@@ -48,39 +61,62 @@ class TestIsAbstractClass(AsyncTestCase):
|
|
|
48
61
|
|
|
49
62
|
async def testWithInheritedAbstractClass(self) -> None:
|
|
50
63
|
"""
|
|
51
|
-
|
|
64
|
+
Validates that the IsAbstractClass validator accepts classes that inherit from abstract classes and remain abstract.
|
|
65
|
+
|
|
66
|
+
This test creates a base abstract class and a derived abstract class, ensuring that the validator
|
|
67
|
+
does not raise an exception when the derived class is still abstract.
|
|
68
|
+
|
|
69
|
+
Returns
|
|
70
|
+
-------
|
|
71
|
+
None
|
|
72
|
+
This method does not return anything. It asserts correct behavior via exceptions and mocks.
|
|
52
73
|
"""
|
|
74
|
+
# Define a base abstract class
|
|
53
75
|
class BaseAbstract(ABC):
|
|
54
76
|
@abstractmethod
|
|
55
77
|
def method1(self):
|
|
56
78
|
pass
|
|
57
79
|
|
|
80
|
+
# Define a derived abstract class that adds another abstract method
|
|
58
81
|
class DerivedAbstract(BaseAbstract):
|
|
59
82
|
@abstractmethod
|
|
60
83
|
def method2(self):
|
|
61
84
|
pass
|
|
62
85
|
|
|
63
|
-
#
|
|
86
|
+
# Patch the reflection method to ensure it is called correctly
|
|
64
87
|
with unittest.mock.patch('orionis.services.introspection.abstract.reflection.ReflectionAbstract.ensureIsAbstractClass') as mock_ensure:
|
|
65
88
|
IsAbstractClass(DerivedAbstract, "transient")
|
|
66
89
|
mock_ensure.assert_called_once_with(DerivedAbstract)
|
|
67
90
|
|
|
68
91
|
async def testWithConcreteImplementation(self) -> None:
|
|
69
92
|
"""
|
|
70
|
-
|
|
93
|
+
Validates that the IsAbstractClass validator raises an error for concrete implementations of abstract classes.
|
|
94
|
+
|
|
95
|
+
This test creates a concrete class that implements all abstract methods and mocks the reflection method
|
|
96
|
+
to raise a TypeError, ensuring that the validator responds with an OrionisContainerTypeError.
|
|
97
|
+
|
|
98
|
+
Returns
|
|
99
|
+
-------
|
|
100
|
+
None
|
|
101
|
+
This method does not return anything. It asserts correct behavior via exceptions and mocks.
|
|
71
102
|
"""
|
|
103
|
+
# Define a base abstract class
|
|
72
104
|
class BaseAbstract(ABC):
|
|
73
105
|
@abstractmethod
|
|
74
106
|
def method(self):
|
|
75
107
|
pass
|
|
76
108
|
|
|
109
|
+
# Define a concrete class that implements the abstract method
|
|
77
110
|
class ConcreteImplementation(BaseAbstract):
|
|
78
111
|
def method(self):
|
|
79
112
|
return "Implemented"
|
|
80
113
|
|
|
81
|
-
#
|
|
82
|
-
with unittest.mock.patch(
|
|
83
|
-
|
|
114
|
+
# Patch the reflection method to simulate failure for concrete classes
|
|
115
|
+
with unittest.mock.patch(
|
|
116
|
+
'orionis.services.introspection.abstract.reflection.ReflectionAbstract.ensureIsAbstractClass',
|
|
117
|
+
side_effect=TypeError("Not an abstract class")
|
|
118
|
+
) as mock_ensure:
|
|
119
|
+
# Assert that the validator raises the expected error
|
|
84
120
|
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
85
121
|
IsAbstractClass(ConcreteImplementation, "singleton")
|
|
86
122
|
|
|
@@ -89,11 +125,23 @@ class TestIsAbstractClass(AsyncTestCase):
|
|
|
89
125
|
|
|
90
126
|
async def testWithNonClassTypes(self) -> None:
|
|
91
127
|
"""
|
|
92
|
-
|
|
128
|
+
Validates that the IsAbstractClass validator raises an error for non-class types.
|
|
129
|
+
|
|
130
|
+
This test iterates over several primitive and non-class values, mocking the reflection method
|
|
131
|
+
to raise a TypeError, and ensures that the validator responds with an OrionisContainerTypeError.
|
|
132
|
+
|
|
133
|
+
Returns
|
|
134
|
+
-------
|
|
135
|
+
None
|
|
136
|
+
This method does not return anything. It asserts correct behavior via exceptions and mocks.
|
|
93
137
|
"""
|
|
94
|
-
# Test with
|
|
138
|
+
# Test with various non-class types
|
|
95
139
|
for invalid_value in [1, "string", [], {}, lambda: None]:
|
|
96
|
-
|
|
97
|
-
|
|
140
|
+
# Patch the reflection method to simulate failure for non-class types
|
|
141
|
+
with unittest.mock.patch(
|
|
142
|
+
'orionis.services.introspection.abstract.reflection.ReflectionAbstract.ensureIsAbstractClass',
|
|
143
|
+
side_effect=TypeError(f"{type(invalid_value)} is not a class")
|
|
144
|
+
) as mock_ensure:
|
|
145
|
+
# Assert that the validator raises the expected error
|
|
98
146
|
with self.assertRaises(OrionisContainerTypeError):
|
|
99
147
|
IsAbstractClass(invalid_value, "transient")
|
|
@@ -3,29 +3,30 @@ from orionis.container.exceptions.type import OrionisContainerTypeError
|
|
|
3
3
|
from orionis.test.cases.asynchronous import AsyncTestCase
|
|
4
4
|
|
|
5
5
|
class TestIsCallable(AsyncTestCase):
|
|
6
|
-
"""
|
|
7
|
-
Test cases for the IsCallable validator in orionis.container.validators.is_callable.
|
|
8
|
-
|
|
9
|
-
Notes
|
|
10
|
-
-----
|
|
11
|
-
This test suite validates the functionality of the IsCallable validator
|
|
12
|
-
which ensures that a provided value is callable.
|
|
13
|
-
"""
|
|
14
6
|
|
|
15
7
|
async def testValidCallables(self) -> None:
|
|
16
8
|
"""
|
|
17
|
-
|
|
9
|
+
Validate that IsCallable accepts valid callable objects without raising exceptions.
|
|
10
|
+
|
|
11
|
+
This test covers various types of callables, including functions, classes with
|
|
12
|
+
a __call__ method, lambda functions, and built-in functions.
|
|
13
|
+
|
|
14
|
+
Returns
|
|
15
|
+
-------
|
|
16
|
+
None
|
|
17
|
+
This method does not return any value. It asserts that no exception is raised
|
|
18
|
+
for valid callables.
|
|
18
19
|
"""
|
|
19
20
|
def simple_function():
|
|
20
|
-
pass
|
|
21
|
+
pass # Simple user-defined function
|
|
21
22
|
|
|
22
23
|
class ClassWithCall:
|
|
23
24
|
def __call__(self):
|
|
24
|
-
pass
|
|
25
|
+
pass # Class instance with __call__ method
|
|
25
26
|
|
|
26
|
-
lambda_func = lambda x: x
|
|
27
|
+
lambda_func = lambda x: x # Lambda function
|
|
27
28
|
|
|
28
|
-
# These should not raise exceptions
|
|
29
|
+
# These should not raise exceptions as they are all callable
|
|
29
30
|
IsCallable(simple_function)
|
|
30
31
|
IsCallable(ClassWithCall())
|
|
31
32
|
IsCallable(lambda_func)
|
|
@@ -34,19 +35,29 @@ class TestIsCallable(AsyncTestCase):
|
|
|
34
35
|
|
|
35
36
|
async def testNonCallables(self) -> None:
|
|
36
37
|
"""
|
|
37
|
-
|
|
38
|
+
Ensure that IsCallable raises OrionisContainerTypeError for non-callable objects.
|
|
39
|
+
|
|
40
|
+
This test iterates over a list of non-callable objects and asserts that the
|
|
41
|
+
expected exception is raised with the correct error message.
|
|
42
|
+
|
|
43
|
+
Returns
|
|
44
|
+
-------
|
|
45
|
+
None
|
|
46
|
+
This method does not return any value. It asserts that exceptions are raised
|
|
47
|
+
for non-callable objects.
|
|
38
48
|
"""
|
|
39
49
|
non_callables = [
|
|
40
|
-
42,
|
|
41
|
-
"string",
|
|
42
|
-
[1, 2, 3],
|
|
43
|
-
{"key": "value"},
|
|
44
|
-
None,
|
|
45
|
-
True,
|
|
46
|
-
(1, 2, 3)
|
|
50
|
+
42, # Integer
|
|
51
|
+
"string", # String
|
|
52
|
+
[1, 2, 3], # List
|
|
53
|
+
{"key": "value"}, # Dictionary
|
|
54
|
+
None, # NoneType
|
|
55
|
+
True, # Boolean
|
|
56
|
+
(1, 2, 3) # Tuple
|
|
47
57
|
]
|
|
48
58
|
|
|
49
59
|
for value in non_callables:
|
|
60
|
+
# Assert that IsCallable raises the expected exception for non-callables
|
|
50
61
|
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
51
62
|
IsCallable(value)
|
|
52
63
|
expected_message = f"Expected a callable type, but got {type(value).__name__} instead."
|
|
@@ -54,19 +65,37 @@ class TestIsCallable(AsyncTestCase):
|
|
|
54
65
|
|
|
55
66
|
async def testClassesAsCallables(self) -> None:
|
|
56
67
|
"""
|
|
57
|
-
|
|
68
|
+
Verify that classes themselves are considered callable by IsCallable.
|
|
69
|
+
|
|
70
|
+
Classes are callable because they can be instantiated. This test ensures
|
|
71
|
+
that passing a class to IsCallable does not raise an exception.
|
|
72
|
+
|
|
73
|
+
Returns
|
|
74
|
+
-------
|
|
75
|
+
None
|
|
76
|
+
This method does not return any value. It asserts that no exception is raised
|
|
77
|
+
for classes.
|
|
58
78
|
"""
|
|
59
79
|
class SimpleClass:
|
|
60
|
-
pass
|
|
80
|
+
pass # Simple class definition
|
|
61
81
|
|
|
62
|
-
#
|
|
82
|
+
# Should not raise an exception since classes are callable
|
|
63
83
|
IsCallable(SimpleClass)
|
|
64
84
|
|
|
65
85
|
async def testBuiltinFunctions(self) -> None:
|
|
66
86
|
"""
|
|
67
|
-
|
|
87
|
+
Confirm that built-in functions are recognized as callable by IsCallable.
|
|
88
|
+
|
|
89
|
+
This test checks several built-in functions to ensure they are accepted
|
|
90
|
+
without raising exceptions.
|
|
91
|
+
|
|
92
|
+
Returns
|
|
93
|
+
-------
|
|
94
|
+
None
|
|
95
|
+
This method does not return any value. It asserts that no exception is raised
|
|
96
|
+
for built-in functions.
|
|
68
97
|
"""
|
|
69
|
-
# These should not raise exceptions
|
|
98
|
+
# These built-in functions should not raise exceptions
|
|
70
99
|
IsCallable(sum)
|
|
71
100
|
IsCallable(map)
|
|
72
101
|
IsCallable(filter)
|
|
@@ -4,39 +4,58 @@ from orionis.container.exceptions.type import OrionisContainerTypeError
|
|
|
4
4
|
from orionis.test.cases.asynchronous import AsyncTestCase
|
|
5
5
|
|
|
6
6
|
class TestIsConcreteClass(AsyncTestCase):
|
|
7
|
-
"""
|
|
8
|
-
Test cases for the IsConcreteClass validator in orionis.container.validators.is_concrete_class.
|
|
9
|
-
|
|
10
|
-
Notes
|
|
11
|
-
-----
|
|
12
|
-
This test suite validates the functionality of the IsConcreteClass validator
|
|
13
|
-
which ensures that a provided class is a concrete (non-abstract) class.
|
|
14
|
-
"""
|
|
15
7
|
|
|
16
8
|
async def testValidConcreteClasses(self) -> None:
|
|
17
9
|
"""
|
|
18
10
|
Test that validation passes for valid concrete classes.
|
|
11
|
+
|
|
12
|
+
This test verifies that the `IsConcreteClass` validator does not raise an exception
|
|
13
|
+
when provided with classes that are concrete (i.e., not abstract and fully implemented).
|
|
14
|
+
|
|
15
|
+
Parameters
|
|
16
|
+
----------
|
|
17
|
+
self : TestIsConcreteClass
|
|
18
|
+
The test case instance.
|
|
19
|
+
|
|
20
|
+
Returns
|
|
21
|
+
-------
|
|
22
|
+
None
|
|
23
|
+
This method does not return anything. It asserts that no exception is raised for valid concrete classes.
|
|
19
24
|
"""
|
|
20
25
|
class SimpleClass:
|
|
21
|
-
pass
|
|
26
|
+
pass # A basic concrete class with no methods
|
|
22
27
|
|
|
23
28
|
class ClassWithInit:
|
|
24
29
|
def __init__(self, value):
|
|
25
|
-
self.value = value
|
|
30
|
+
self.value = value # Concrete class with an initializer
|
|
26
31
|
|
|
27
|
-
# These should not raise exceptions
|
|
32
|
+
# These should not raise exceptions since both are concrete classes
|
|
28
33
|
IsConcreteClass(SimpleClass, "singleton")
|
|
29
34
|
IsConcreteClass(ClassWithInit, "transient")
|
|
30
35
|
|
|
31
36
|
async def testAbstractClasses(self) -> None:
|
|
32
37
|
"""
|
|
33
38
|
Test that validation fails for abstract classes.
|
|
39
|
+
|
|
40
|
+
This test ensures that the `IsConcreteClass` validator raises an `OrionisContainerTypeError`
|
|
41
|
+
when provided with an abstract class.
|
|
42
|
+
|
|
43
|
+
Parameters
|
|
44
|
+
----------
|
|
45
|
+
self : TestIsConcreteClass
|
|
46
|
+
The test case instance.
|
|
47
|
+
|
|
48
|
+
Returns
|
|
49
|
+
-------
|
|
50
|
+
None
|
|
51
|
+
This method does not return anything. It asserts that an exception is raised for abstract classes.
|
|
34
52
|
"""
|
|
35
53
|
class AbstractBase(ABC):
|
|
36
54
|
@abstractmethod
|
|
37
55
|
def abstract_method(self):
|
|
38
|
-
pass
|
|
56
|
+
pass # Abstract method, making this class abstract
|
|
39
57
|
|
|
58
|
+
# Should raise an exception because AbstractBase is abstract
|
|
40
59
|
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
41
60
|
IsConcreteClass(AbstractBase, "scoped")
|
|
42
61
|
self.assertIn("Unexpected error registering scoped service", str(context.exception))
|
|
@@ -44,15 +63,31 @@ class TestIsConcreteClass(AsyncTestCase):
|
|
|
44
63
|
async def testNonClassTypes(self) -> None:
|
|
45
64
|
"""
|
|
46
65
|
Test that validation fails for non-class types.
|
|
66
|
+
|
|
67
|
+
This test checks that the `IsConcreteClass` validator raises an `OrionisContainerTypeError`
|
|
68
|
+
when provided with values that are not classes (e.g., integers, strings, functions).
|
|
69
|
+
|
|
70
|
+
Parameters
|
|
71
|
+
----------
|
|
72
|
+
self : TestIsConcreteClass
|
|
73
|
+
The test case instance.
|
|
74
|
+
|
|
75
|
+
Returns
|
|
76
|
+
-------
|
|
77
|
+
None
|
|
78
|
+
This method does not return anything. It asserts that an exception is raised for non-class types.
|
|
47
79
|
"""
|
|
80
|
+
# Should raise an exception for integer input
|
|
48
81
|
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
49
82
|
IsConcreteClass(42, "singleton")
|
|
50
83
|
self.assertIn("Unexpected error registering singleton service", str(context.exception))
|
|
51
84
|
|
|
85
|
+
# Should raise an exception for string input
|
|
52
86
|
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
53
87
|
IsConcreteClass("string", "scoped")
|
|
54
88
|
self.assertIn("Unexpected error registering scoped service", str(context.exception))
|
|
55
89
|
|
|
90
|
+
# Should raise an exception for function input
|
|
56
91
|
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
57
92
|
IsConcreteClass(lambda x: x, "transient")
|
|
58
93
|
self.assertIn("Unexpected error registering transient service", str(context.exception))
|
|
@@ -60,22 +95,49 @@ class TestIsConcreteClass(AsyncTestCase):
|
|
|
60
95
|
async def testInheritedConcreteClasses(self) -> None:
|
|
61
96
|
"""
|
|
62
97
|
Test that validation passes for concrete classes that inherit from abstract classes.
|
|
98
|
+
|
|
99
|
+
This test verifies that the `IsConcreteClass` validator does not raise an exception
|
|
100
|
+
for classes that inherit from abstract base classes but implement all abstract methods,
|
|
101
|
+
making them concrete.
|
|
102
|
+
|
|
103
|
+
Parameters
|
|
104
|
+
----------
|
|
105
|
+
self : TestIsConcreteClass
|
|
106
|
+
The test case instance.
|
|
107
|
+
|
|
108
|
+
Returns
|
|
109
|
+
-------
|
|
110
|
+
None
|
|
111
|
+
This method does not return anything. It asserts that no exception is raised for concrete subclasses.
|
|
63
112
|
"""
|
|
64
113
|
class AbstractBase(ABC):
|
|
65
114
|
@abstractmethod
|
|
66
115
|
def abstract_method(self):
|
|
67
|
-
pass
|
|
116
|
+
pass # Abstract method
|
|
68
117
|
|
|
69
118
|
class ConcreteImplementation(AbstractBase):
|
|
70
119
|
def abstract_method(self):
|
|
71
|
-
return "Implemented"
|
|
120
|
+
return "Implemented" # Implements all abstract methods
|
|
72
121
|
|
|
73
|
-
#
|
|
122
|
+
# Should not raise an exception since all abstract methods are implemented
|
|
74
123
|
IsConcreteClass(ConcreteImplementation, "singleton")
|
|
75
124
|
|
|
76
125
|
async def testPartialImplementations(self) -> None:
|
|
77
126
|
"""
|
|
78
127
|
Test that validation fails for classes that don't implement all abstract methods.
|
|
128
|
+
|
|
129
|
+
This test ensures that the `IsConcreteClass` validator raises an `OrionisContainerTypeError`
|
|
130
|
+
when a class inherits from an abstract base class but does not implement all required abstract methods.
|
|
131
|
+
|
|
132
|
+
Parameters
|
|
133
|
+
----------
|
|
134
|
+
self : TestIsConcreteClass
|
|
135
|
+
The test case instance.
|
|
136
|
+
|
|
137
|
+
Returns
|
|
138
|
+
-------
|
|
139
|
+
None
|
|
140
|
+
This method does not return anything. It asserts that an exception is raised for partial implementations.
|
|
79
141
|
"""
|
|
80
142
|
class AbstractBase(ABC):
|
|
81
143
|
@abstractmethod
|
|
@@ -88,10 +150,11 @@ class TestIsConcreteClass(AsyncTestCase):
|
|
|
88
150
|
|
|
89
151
|
class PartialImplementation(AbstractBase):
|
|
90
152
|
def method1(self):
|
|
91
|
-
return "Implemented"
|
|
153
|
+
return "Implemented" # Only one abstract method is implemented
|
|
92
154
|
|
|
93
|
-
# method2 is not implemented
|
|
155
|
+
# method2 is not implemented, so this class remains abstract
|
|
94
156
|
|
|
157
|
+
# Should raise an exception since not all abstract methods are implemented
|
|
95
158
|
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
96
159
|
IsConcreteClass(PartialImplementation, "scoped")
|
|
97
160
|
self.assertIn("Unexpected error registering scoped service", str(context.exception))
|
|
@@ -4,21 +4,20 @@ from orionis.container.exceptions.type import OrionisContainerTypeError
|
|
|
4
4
|
from orionis.test.cases.asynchronous import AsyncTestCase
|
|
5
5
|
|
|
6
6
|
class TestIsInstance(AsyncTestCase):
|
|
7
|
-
"""
|
|
8
|
-
Test cases for the IsInstance validator in orionis.container.validators.is_instance.
|
|
9
|
-
|
|
10
|
-
Notes
|
|
11
|
-
-----
|
|
12
|
-
This test suite validates the functionality of the IsInstance validator
|
|
13
|
-
which ensures that a provided object is a valid instance (not a class or abstract type).
|
|
14
|
-
"""
|
|
15
7
|
|
|
16
8
|
async def testValidInstances(self) -> None:
|
|
17
9
|
"""
|
|
18
|
-
|
|
19
|
-
"""
|
|
10
|
+
Validate that IsInstance accepts valid object instances.
|
|
20
11
|
|
|
21
|
-
|
|
12
|
+
This test checks that IsInstance does not raise an exception when provided with
|
|
13
|
+
instances of user-defined classes, including those with and without an __init__ method.
|
|
14
|
+
|
|
15
|
+
Returns
|
|
16
|
+
-------
|
|
17
|
+
None
|
|
18
|
+
This method does not return any value.
|
|
19
|
+
"""
|
|
20
|
+
# Custom class instance
|
|
22
21
|
class SimpleClass:
|
|
23
22
|
pass
|
|
24
23
|
|
|
@@ -27,17 +26,28 @@ class TestIsInstance(AsyncTestCase):
|
|
|
27
26
|
def __init__(self, value):
|
|
28
27
|
self.value = value
|
|
29
28
|
|
|
29
|
+
# Should not raise an exception for valid instances
|
|
30
30
|
IsInstance(SimpleClass())
|
|
31
31
|
IsInstance(ClassWithInit(42))
|
|
32
32
|
|
|
33
33
|
async def testInvalidClasses(self) -> None:
|
|
34
34
|
"""
|
|
35
|
-
|
|
35
|
+
Ensure IsInstance raises an error when provided with class objects instead of instances.
|
|
36
|
+
|
|
37
|
+
This test verifies that passing class types (rather than instances) to IsInstance
|
|
38
|
+
results in an OrionisContainerTypeError.
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
-------
|
|
42
|
+
None
|
|
43
|
+
This method does not return any value.
|
|
36
44
|
"""
|
|
45
|
+
# Passing built-in type should raise an error
|
|
37
46
|
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
38
47
|
IsInstance(str)
|
|
39
48
|
self.assertIn("Error registering instance", str(context.exception))
|
|
40
49
|
|
|
50
|
+
# Passing user-defined class should raise an error
|
|
41
51
|
class TestClass:
|
|
42
52
|
pass
|
|
43
53
|
|
|
@@ -47,29 +57,48 @@ class TestIsInstance(AsyncTestCase):
|
|
|
47
57
|
|
|
48
58
|
async def testAbstractClasses(self) -> None:
|
|
49
59
|
"""
|
|
50
|
-
Test
|
|
60
|
+
Test IsInstance behavior with abstract classes and their concrete implementations.
|
|
61
|
+
|
|
62
|
+
This test ensures that abstract classes are not accepted as valid instances,
|
|
63
|
+
but instances of concrete subclasses are accepted.
|
|
64
|
+
|
|
65
|
+
Returns
|
|
66
|
+
-------
|
|
67
|
+
None
|
|
68
|
+
This method does not return any value.
|
|
51
69
|
"""
|
|
70
|
+
# Define an abstract base class
|
|
52
71
|
class AbstractBase(ABC):
|
|
53
72
|
@abstractmethod
|
|
54
73
|
def abstract_method(self):
|
|
55
74
|
pass
|
|
56
75
|
|
|
76
|
+
# Concrete implementation of the abstract base
|
|
57
77
|
class ConcreteImplementation(AbstractBase):
|
|
58
78
|
def abstract_method(self):
|
|
59
79
|
return "Implemented"
|
|
60
80
|
|
|
61
|
-
# Abstract class should
|
|
81
|
+
# Abstract class should raise an error
|
|
62
82
|
with self.assertRaises(OrionisContainerTypeError) as context:
|
|
63
83
|
IsInstance(AbstractBase)
|
|
64
84
|
self.assertIn("Error registering instance", str(context.exception))
|
|
65
85
|
|
|
66
|
-
#
|
|
86
|
+
# Instance of concrete implementation should not raise an error
|
|
67
87
|
IsInstance(ConcreteImplementation())
|
|
68
88
|
|
|
69
89
|
async def testTypeObjects(self) -> None:
|
|
70
90
|
"""
|
|
71
|
-
|
|
91
|
+
Verify that IsInstance raises errors for type objects.
|
|
92
|
+
|
|
93
|
+
This test checks that passing type objects such as `type`, `int`, or `list`
|
|
94
|
+
to IsInstance results in an OrionisContainerTypeError.
|
|
95
|
+
|
|
96
|
+
Returns
|
|
97
|
+
-------
|
|
98
|
+
None
|
|
99
|
+
This method does not return any value.
|
|
72
100
|
"""
|
|
101
|
+
# Should raise error for built-in type objects
|
|
73
102
|
with self.assertRaises(OrionisContainerTypeError):
|
|
74
103
|
IsInstance(type)
|
|
75
104
|
|
|
@@ -81,25 +110,41 @@ class TestIsInstance(AsyncTestCase):
|
|
|
81
110
|
|
|
82
111
|
async def testNoneValue(self) -> None:
|
|
83
112
|
"""
|
|
84
|
-
Test validation with None value.
|
|
113
|
+
Test IsInstance validation with None value.
|
|
114
|
+
|
|
115
|
+
This test verifies that passing None to IsInstance raises an OrionisContainerTypeError,
|
|
116
|
+
even though None is a valid instance in Python.
|
|
117
|
+
|
|
118
|
+
Returns
|
|
119
|
+
-------
|
|
120
|
+
None
|
|
121
|
+
This method does not return any value.
|
|
85
122
|
"""
|
|
86
|
-
#
|
|
123
|
+
# Should raise error for None value
|
|
87
124
|
with self.assertRaises(OrionisContainerTypeError):
|
|
88
125
|
IsInstance(None)
|
|
89
126
|
|
|
90
127
|
async def testCallables(self) -> None:
|
|
91
128
|
"""
|
|
92
|
-
Test validation with callable objects.
|
|
129
|
+
Test IsInstance validation with callable objects.
|
|
130
|
+
|
|
131
|
+
This test checks that passing function objects and lambda functions to IsInstance
|
|
132
|
+
raises an OrionisContainerTypeError, while passing their types also raises an error.
|
|
133
|
+
|
|
134
|
+
Returns
|
|
135
|
+
-------
|
|
136
|
+
None
|
|
137
|
+
This method does not return any value.
|
|
93
138
|
"""
|
|
94
|
-
#
|
|
139
|
+
# Define a function for testing
|
|
95
140
|
def test_function():
|
|
96
141
|
pass
|
|
97
142
|
|
|
98
|
-
#
|
|
143
|
+
# Should raise error for function and lambda instances
|
|
99
144
|
with self.assertRaises(OrionisContainerTypeError):
|
|
100
145
|
IsInstance(test_function)
|
|
101
146
|
IsInstance(lambda x: x * 2)
|
|
102
147
|
|
|
103
|
-
#
|
|
148
|
+
# Should raise error for type of function
|
|
104
149
|
with self.assertRaises(OrionisContainerTypeError):
|
|
105
150
|
IsInstance(type(test_function))
|