orionis 0.285.0__py3-none-any.whl → 0.287.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 (67) hide show
  1. orionis/metadata/framework.py +1 -1
  2. orionis/services/asynchrony/contracts/__init__.py +0 -0
  3. orionis/services/asynchrony/contracts/coroutines.py +24 -0
  4. orionis/services/asynchrony/coroutines.py +58 -19
  5. orionis/services/asynchrony/exceptions/coroutine_exception.py +8 -15
  6. orionis/services/environment/contracts/env.py +45 -50
  7. orionis/services/environment/dot_env.py +205 -181
  8. orionis/services/environment/env.py +68 -85
  9. orionis/services/environment/exceptions/environment_value_error.py +18 -0
  10. orionis/services/environment/exceptions/environment_value_exception.py +23 -0
  11. orionis/services/environment/type_hint.py +559 -0
  12. orionis/test/exceptions/test_config_exception.py +8 -17
  13. orionis/test/exceptions/test_failure_exception.py +27 -27
  14. orionis/test/exceptions/test_persistence_error.py +10 -20
  15. orionis/test/exceptions/test_runtime_error.py +8 -15
  16. orionis/test/exceptions/test_value_error.py +8 -15
  17. orionis/test/logs/history.py +3 -5
  18. {orionis-0.285.0.dist-info → orionis-0.287.0.dist-info}/METADATA +1 -1
  19. {orionis-0.285.0.dist-info → orionis-0.287.0.dist-info}/RECORD +66 -62
  20. tests/example/test_example.py +5 -2
  21. tests/foundation/config/app/test_app.py +13 -3
  22. tests/foundation/config/auth/test_auth.py +9 -4
  23. tests/foundation/config/cache/test_cache.py +60 -15
  24. tests/foundation/config/cache/test_cache_file.py +62 -14
  25. tests/foundation/config/cache/test_cache_stores.py +74 -14
  26. tests/foundation/config/cors/test_cors.py +102 -33
  27. tests/foundation/config/database/test_database.py +38 -14
  28. tests/foundation/config/database/test_database_connections.py +79 -5
  29. tests/foundation/config/database/test_database_mysql.py +138 -15
  30. tests/foundation/config/database/test_database_oracle.py +110 -26
  31. tests/foundation/config/database/test_database_pgsql.py +96 -26
  32. tests/foundation/config/database/test_database_sqlite.py +56 -2
  33. tests/foundation/config/exceptions/test_exceptions_integrity.py +44 -10
  34. tests/foundation/config/filesystems/test_filesystems.py +64 -14
  35. tests/foundation/config/filesystems/test_filesystems_aws.py +45 -7
  36. tests/foundation/config/filesystems/test_filesystems_disks.py +78 -8
  37. tests/foundation/config/filesystems/test_filesystems_local.py +66 -18
  38. tests/foundation/config/filesystems/test_filesystems_public.py +37 -0
  39. tests/foundation/config/logging/test_logging.py +75 -11
  40. tests/foundation/config/logging/test_logging_channels.py +79 -2
  41. tests/foundation/config/logging/test_logging_chunked.py +85 -12
  42. tests/foundation/config/logging/test_logging_daily.py +79 -12
  43. tests/foundation/config/logging/test_logging_hourly.py +68 -2
  44. tests/foundation/config/logging/test_logging_monthly.py +48 -2
  45. tests/foundation/config/logging/test_logging_stack.py +49 -14
  46. tests/foundation/config/logging/test_logging_weekly.py +92 -2
  47. tests/foundation/config/mail/test_mail.py +87 -15
  48. tests/foundation/config/mail/test_mail_file.py +40 -4
  49. tests/foundation/config/mail/test_mail_mailers.py +56 -8
  50. tests/foundation/config/mail/test_mail_smtp.py +58 -14
  51. tests/foundation/config/queue/test_queue.py +62 -9
  52. tests/foundation/config/queue/test_queue_brokers.py +27 -10
  53. tests/foundation/config/queue/test_queue_database.py +53 -15
  54. tests/foundation/config/root/test_root_paths.py +69 -2
  55. tests/foundation/config/session/test_session.py +30 -1
  56. tests/foundation/config/startup/test_config_startup.py +77 -7
  57. tests/foundation/config/testing/test_testing.py +68 -0
  58. tests/patterns/singleton/test_singleton.py +10 -1
  59. tests/services/asynchrony/test_async_io.py +4 -4
  60. tests/services/environment/test_env.py +3 -4
  61. tests/testing/test_testing_result.py +56 -19
  62. tests/testing/test_testing_unit.py +93 -24
  63. orionis/services/environment/exceptions/value_exception.py +0 -27
  64. {orionis-0.285.0.dist-info → orionis-0.287.0.dist-info}/WHEEL +0 -0
  65. {orionis-0.285.0.dist-info → orionis-0.287.0.dist-info}/licenses/LICENCE +0 -0
  66. {orionis-0.285.0.dist-info → orionis-0.287.0.dist-info}/top_level.txt +0 -0
  67. {orionis-0.285.0.dist-info → orionis-0.287.0.dist-info}/zip-safe +0 -0
@@ -6,12 +6,23 @@ from orionis.unittesting import TestCase
6
6
  class TestConfigChunked(TestCase):
7
7
  """
8
8
  Test cases for the Chunked logging configuration class.
9
+
10
+ Notes
11
+ -----
12
+ These tests validate the integrity, default values, and behavior of the
13
+ `Chunked` logging configuration entity, including its attributes and methods.
9
14
  """
10
15
 
11
16
  async def testDefaultValues(self):
12
17
  """
13
- Test that Chunked instance is created with correct default values.
14
- Verifies default path, level, mb_size and files match expected values.
18
+ Test default values of Chunked instance.
19
+
20
+ Ensures that a `Chunked` instance is created with the correct default values
21
+ for `path`, `level`, `mb_size`, and `files`.
22
+
23
+ Returns
24
+ -------
25
+ None
15
26
  """
16
27
  chunked = Chunked()
17
28
  self.assertEqual(chunked.path, "storage/log/application.log")
@@ -21,8 +32,14 @@ class TestConfigChunked(TestCase):
21
32
 
22
33
  async def testPathValidation(self):
23
34
  """
24
- Test path attribute validation.
25
- Verifies that empty or non-string paths raise exceptions.
35
+ Test validation of the `path` attribute.
36
+
37
+ Verifies that empty or non-string paths raise `OrionisIntegrityException`.
38
+ Also checks that a valid path does not raise an exception.
39
+
40
+ Returns
41
+ -------
42
+ None
26
43
  """
27
44
  with self.assertRaises(OrionisIntegrityException):
28
45
  Chunked(path="")
@@ -35,7 +52,14 @@ class TestConfigChunked(TestCase):
35
52
 
36
53
  async def testLevelValidation(self):
37
54
  """
38
- Test level attribute validation with different input types.
55
+ Test validation of the `level` attribute.
56
+
57
+ Checks that the `level` can be set using a string, integer, or enum,
58
+ and that invalid values raise `OrionisIntegrityException`.
59
+
60
+ Returns
61
+ -------
62
+ None
39
63
  """
40
64
  # Test string level
41
65
  chunked = Chunked(level="debug")
@@ -59,7 +83,14 @@ class TestConfigChunked(TestCase):
59
83
 
60
84
  async def testMbSizeValidation(self):
61
85
  """
62
- Test mb_size attribute validation with different input formats.
86
+ Test validation of the `mb_size` attribute.
87
+
88
+ Ensures that valid integer and string formats are accepted, and invalid
89
+ values raise `OrionisIntegrityException`.
90
+
91
+ Returns
92
+ -------
93
+ None
63
94
  """
64
95
  # Test valid integer values
65
96
  try:
@@ -90,7 +121,14 @@ class TestConfigChunked(TestCase):
90
121
 
91
122
  async def testFilesValidation(self):
92
123
  """
93
- Test files attribute validation.
124
+ Test validation of the `files` attribute.
125
+
126
+ Ensures that valid integer values are accepted, and invalid values raise
127
+ `OrionisIntegrityException`.
128
+
129
+ Returns
130
+ -------
131
+ None
94
132
  """
95
133
  # Test valid values
96
134
  try:
@@ -109,7 +147,14 @@ class TestConfigChunked(TestCase):
109
147
 
110
148
  async def testWhitespaceHandling(self):
111
149
  """
112
- Test whitespace handling in path and level attributes.
150
+ Test handling of whitespace in `path` and `level` attributes.
151
+
152
+ Ensures that leading and trailing whitespace in `path` and `level` are
153
+ handled as expected.
154
+
155
+ Returns
156
+ -------
157
+ None
113
158
  """
114
159
  chunked = Chunked(path=" logs/app.log ", level=" debug ")
115
160
  self.assertEqual(chunked.path, " logs/app.log ")
@@ -117,7 +162,14 @@ class TestConfigChunked(TestCase):
117
162
 
118
163
  async def testToDictMethod(self):
119
164
  """
120
- Test that toDict returns proper dictionary representation.
165
+ Test the `toDict` method.
166
+
167
+ Ensures that `toDict` returns a dictionary representation of the instance
168
+ with correct values.
169
+
170
+ Returns
171
+ -------
172
+ None
121
173
  """
122
174
  chunked = Chunked()
123
175
  chunked_dict = chunked.toDict()
@@ -130,7 +182,14 @@ class TestConfigChunked(TestCase):
130
182
 
131
183
  async def testCustomValuesToDict(self):
132
184
  """
133
- Test that custom values are properly included in dictionary.
185
+ Test `toDict` with custom values.
186
+
187
+ Ensures that custom values provided to the constructor are correctly
188
+ reflected in the dictionary representation.
189
+
190
+ Returns
191
+ -------
192
+ None
134
193
  """
135
194
  custom_chunked = Chunked(
136
195
  path="custom/logs/app.log",
@@ -146,7 +205,14 @@ class TestConfigChunked(TestCase):
146
205
 
147
206
  async def testHashability(self):
148
207
  """
149
- Test that Chunked maintains hashability due to unsafe_hash=True.
208
+ Test hashability of Chunked instances.
209
+
210
+ Ensures that `Chunked` instances are hashable and can be used in sets,
211
+ due to `unsafe_hash=True`.
212
+
213
+ Returns
214
+ -------
215
+ None
150
216
  """
151
217
  chunked1 = Chunked()
152
218
  chunked2 = Chunked()
@@ -160,7 +226,14 @@ class TestConfigChunked(TestCase):
160
226
 
161
227
  async def testKwOnlyInitialization(self):
162
228
  """
163
- Test that Chunked enforces keyword-only initialization.
229
+ Test enforcement of keyword-only initialization.
230
+
231
+ Ensures that `Chunked` cannot be initialized with positional arguments,
232
+ and raises a `TypeError` if attempted.
233
+
234
+ Returns
235
+ -------
236
+ None
164
237
  """
165
238
  with self.assertRaises(TypeError):
166
239
  Chunked("path.log", "info", 10, 5)
@@ -7,12 +7,22 @@ from orionis.unittesting import TestCase
7
7
  class TestConfigDaily(TestCase):
8
8
  """
9
9
  Test cases for the Daily logging configuration class.
10
+
11
+ This class contains unit tests for the `Daily` logging configuration entity,
12
+ validating its default values, attribute validation, dictionary conversion,
13
+ hashability, and keyword-only initialization.
10
14
  """
11
15
 
12
16
  async def testDefaultValues(self):
13
17
  """
14
- Test that Daily instance is created with correct default values.
15
- Verifies default path, level, retention_days and at time match expected values.
18
+ Test creation of Daily instance with default values.
19
+
20
+ Ensures that the default path, level, retention_days, and at time
21
+ are set as expected.
22
+
23
+ Returns
24
+ -------
25
+ None
16
26
  """
17
27
  daily = Daily()
18
28
  self.assertEqual(daily.path, "storage/log/application.log")
@@ -22,8 +32,14 @@ class TestConfigDaily(TestCase):
22
32
 
23
33
  async def testPathValidation(self):
24
34
  """
25
- Test path attribute validation.
26
- Verifies that empty or non-string paths raise exceptions.
35
+ Test validation of the path attribute.
36
+
37
+ Verifies that empty or non-string paths raise exceptions, and that
38
+ valid paths are accepted.
39
+
40
+ Returns
41
+ -------
42
+ None
27
43
  """
28
44
  with self.assertRaises(OrionisIntegrityException):
29
45
  Daily(path="")
@@ -36,7 +52,14 @@ class TestConfigDaily(TestCase):
36
52
 
37
53
  async def testLevelValidation(self):
38
54
  """
39
- Test level attribute validation with different input types.
55
+ Test validation of the level attribute.
56
+
57
+ Checks that string, integer, and enum values are accepted for level,
58
+ and that invalid values raise exceptions.
59
+
60
+ Returns
61
+ -------
62
+ None
40
63
  """
41
64
  # Test string level
42
65
  daily = Daily(level="debug")
@@ -60,7 +83,13 @@ class TestConfigDaily(TestCase):
60
83
 
61
84
  async def testRetentionDaysValidation(self):
62
85
  """
63
- Test retention_days attribute validation.
86
+ Test validation of the retention_days attribute.
87
+
88
+ Ensures that valid values are accepted and invalid values raise exceptions.
89
+
90
+ Returns
91
+ -------
92
+ None
64
93
  """
65
94
  # Test valid values
66
95
  try:
@@ -82,7 +111,14 @@ class TestConfigDaily(TestCase):
82
111
 
83
112
  async def testAtTimeValidation(self):
84
113
  """
85
- Test at time attribute validation and conversion.
114
+ Test validation and conversion of the at attribute.
115
+
116
+ Checks that a `datetime.time` object is properly converted and that
117
+ invalid types raise exceptions.
118
+
119
+ Returns
120
+ -------
121
+ None
86
122
  """
87
123
  # Test time object
88
124
  daily = Daily(at=time(12, 30))
@@ -96,7 +132,13 @@ class TestConfigDaily(TestCase):
96
132
 
97
133
  async def testWhitespaceHandling(self):
98
134
  """
99
- Test whitespace handling in path and level attributes.
135
+ Test handling of whitespace in path and level attributes.
136
+
137
+ Ensures that whitespace in path and level is preserved or handled as expected.
138
+
139
+ Returns
140
+ -------
141
+ None
100
142
  """
101
143
  daily = Daily(path=" logs/app.log ", level=" debug ")
102
144
  self.assertEqual(daily.path, " logs/app.log ")
@@ -104,7 +146,14 @@ class TestConfigDaily(TestCase):
104
146
 
105
147
  async def testToDictMethod(self):
106
148
  """
107
- Test that toDict returns proper dictionary representation.
149
+ Test the toDict method for correct dictionary representation.
150
+
151
+ Ensures that the dictionary returned by toDict contains the correct
152
+ default values.
153
+
154
+ Returns
155
+ -------
156
+ None
108
157
  """
109
158
  daily = Daily()
110
159
  daily_dict = daily.toDict()
@@ -117,7 +166,13 @@ class TestConfigDaily(TestCase):
117
166
 
118
167
  async def testCustomValuesToDict(self):
119
168
  """
120
- Test that custom values are properly included in dictionary.
169
+ Test toDict method with custom values.
170
+
171
+ Ensures that custom values are correctly represented in the dictionary.
172
+
173
+ Returns
174
+ -------
175
+ None
121
176
  """
122
177
  custom_daily = Daily(
123
178
  path="custom/logs/app.log",
@@ -133,7 +188,13 @@ class TestConfigDaily(TestCase):
133
188
 
134
189
  async def testHashability(self):
135
190
  """
136
- Test that Daily maintains hashability due to unsafe_hash=True.
191
+ Test hashability of Daily instances.
192
+
193
+ Ensures that Daily instances are hashable and can be used in sets.
194
+
195
+ Returns
196
+ -------
197
+ None
137
198
  """
138
199
  daily1 = Daily()
139
200
  daily2 = Daily()
@@ -147,7 +208,13 @@ class TestConfigDaily(TestCase):
147
208
 
148
209
  async def testKwOnlyInitialization(self):
149
210
  """
150
- Test that Daily enforces keyword-only initialization.
211
+ Test enforcement of keyword-only initialization.
212
+
213
+ Ensures that positional arguments raise a TypeError.
214
+
215
+ Returns
216
+ -------
217
+ None
151
218
  """
152
219
  with self.assertRaises(TypeError):
153
220
  Daily("path.log", "info", 7, time(0, 0))
@@ -6,12 +6,22 @@ from orionis.unittesting import TestCase
6
6
  class TestConfigHourly(TestCase):
7
7
  """
8
8
  Test cases for the Hourly logging configuration class.
9
+
10
+ This class contains unit tests for the `Hourly` logging configuration entity,
11
+ verifying its default values, attribute validation, dictionary representation,
12
+ hashability, and keyword-only initialization enforcement.
9
13
  """
10
14
 
11
15
  async def testDefaultValues(self):
12
16
  """
13
17
  Test that Hourly instance is created with correct default values.
14
- Verifies default path, level and retention_hours match expected values.
18
+
19
+ Verifies that the default `path`, `level`, and `retention_hours` attributes
20
+ of the Hourly instance match the expected values.
21
+
22
+ Returns
23
+ -------
24
+ None
15
25
  """
16
26
  hourly = Hourly()
17
27
  self.assertEqual(hourly.path, "storage/log/application.log")
@@ -21,7 +31,14 @@ class TestConfigHourly(TestCase):
21
31
  async def testPathValidation(self):
22
32
  """
23
33
  Test path attribute validation.
24
- Verifies that empty or non-string paths raise exceptions.
34
+
35
+ Ensures that invalid values for the `path` attribute, such as empty strings
36
+ or non-string types, raise an `OrionisIntegrityException`. Also verifies that
37
+ valid paths do not raise exceptions.
38
+
39
+ Returns
40
+ -------
41
+ None
25
42
  """
26
43
  with self.assertRaises(OrionisIntegrityException):
27
44
  Hourly(path="")
@@ -35,6 +52,13 @@ class TestConfigHourly(TestCase):
35
52
  async def testLevelValidation(self):
36
53
  """
37
54
  Test level attribute validation with different input types.
55
+
56
+ Checks that the `level` attribute accepts string, integer, and enum values,
57
+ and that invalid values raise an `OrionisIntegrityException`.
58
+
59
+ Returns
60
+ -------
61
+ None
38
62
  """
39
63
  # Test string level
40
64
  hourly = Hourly(level="debug")
@@ -59,6 +83,13 @@ class TestConfigHourly(TestCase):
59
83
  async def testRetentionHoursValidation(self):
60
84
  """
61
85
  Test retention_hours attribute validation.
86
+
87
+ Ensures that valid values for `retention_hours` are accepted and invalid
88
+ values raise an `OrionisIntegrityException`.
89
+
90
+ Returns
91
+ -------
92
+ None
62
93
  """
63
94
  # Test valid values
64
95
  try:
@@ -81,6 +112,13 @@ class TestConfigHourly(TestCase):
81
112
  async def testWhitespaceHandling(self):
82
113
  """
83
114
  Test whitespace handling in path and level attributes.
115
+
116
+ Verifies that leading and trailing whitespace in the `path` and `level`
117
+ attributes are handled as expected.
118
+
119
+ Returns
120
+ -------
121
+ None
84
122
  """
85
123
  hourly = Hourly(path=" logs/app.log ", level=" debug ")
86
124
  self.assertEqual(hourly.path, " logs/app.log ")
@@ -89,6 +127,13 @@ class TestConfigHourly(TestCase):
89
127
  async def testToDictMethod(self):
90
128
  """
91
129
  Test that toDict returns proper dictionary representation.
130
+
131
+ Ensures that the `toDict` method returns a dictionary with the correct
132
+ attribute values.
133
+
134
+ Returns
135
+ -------
136
+ None
92
137
  """
93
138
  hourly = Hourly()
94
139
  hourly_dict = hourly.toDict()
@@ -100,6 +145,13 @@ class TestConfigHourly(TestCase):
100
145
  async def testCustomValuesToDict(self):
101
146
  """
102
147
  Test that custom values are properly included in dictionary.
148
+
149
+ Verifies that custom values provided to the Hourly instance are correctly
150
+ reflected in the dictionary returned by `toDict`.
151
+
152
+ Returns
153
+ -------
154
+ None
103
155
  """
104
156
  custom_hourly = Hourly(
105
157
  path="custom/logs/app.log",
@@ -114,6 +166,13 @@ class TestConfigHourly(TestCase):
114
166
  async def testHashability(self):
115
167
  """
116
168
  Test that Hourly maintains hashability due to unsafe_hash=True.
169
+
170
+ Ensures that Hourly instances can be added to a set and that their
171
+ hashability is preserved.
172
+
173
+ Returns
174
+ -------
175
+ None
117
176
  """
118
177
  hourly1 = Hourly()
119
178
  hourly2 = Hourly()
@@ -126,6 +185,13 @@ class TestConfigHourly(TestCase):
126
185
  async def testKwOnlyInitialization(self):
127
186
  """
128
187
  Test that Hourly enforces keyword-only initialization.
188
+
189
+ Verifies that attempting to initialize Hourly with positional arguments
190
+ raises a TypeError.
191
+
192
+ Returns
193
+ -------
194
+ None
129
195
  """
130
196
  with self.assertRaises(TypeError):
131
197
  Hourly("path.log", "info", 24)
@@ -6,12 +6,23 @@ from orionis.unittesting import TestCase
6
6
  class TestConfigMonthly(TestCase):
7
7
  """
8
8
  Test cases for the Monthly logging configuration class.
9
+
10
+ Notes
11
+ -----
12
+ This test suite verifies the correct behavior of the `Monthly` logging configuration,
13
+ including default values, attribute validation, dictionary conversion, hashability,
14
+ and keyword-only initialization.
9
15
  """
10
16
 
11
17
  async def testDefaultValues(self):
12
18
  """
13
19
  Test that Monthly instance is created with correct default values.
14
- Verifies default path, level and retention_months match expected values.
20
+
21
+ Verifies
22
+ --------
23
+ - Default path is "storage/log/application.log".
24
+ - Default level is `Level.INFO.value`.
25
+ - Default retention_months is 4.
15
26
  """
16
27
  monthly = Monthly()
17
28
  self.assertEqual(monthly.path, "storage/log/application.log")
@@ -21,7 +32,11 @@ class TestConfigMonthly(TestCase):
21
32
  async def testPathValidation(self):
22
33
  """
23
34
  Test path attribute validation.
24
- Verifies that empty or non-string paths raise exceptions.
35
+
36
+ Verifies
37
+ --------
38
+ - Empty or non-string paths raise `OrionisIntegrityException`.
39
+ - Valid string paths do not raise exceptions.
25
40
  """
26
41
  with self.assertRaises(OrionisIntegrityException):
27
42
  Monthly(path="")
@@ -35,6 +50,11 @@ class TestConfigMonthly(TestCase):
35
50
  async def testLevelValidation(self):
36
51
  """
37
52
  Test level attribute validation with different input types.
53
+
54
+ Verifies
55
+ --------
56
+ - Accepts string, int, and enum values for level.
57
+ - Invalid level values raise `OrionisIntegrityException`.
38
58
  """
39
59
  # Test string level
40
60
  monthly = Monthly(level="debug")
@@ -59,6 +79,11 @@ class TestConfigMonthly(TestCase):
59
79
  async def testRetentionMonthsValidation(self):
60
80
  """
61
81
  Test retention_months attribute validation.
82
+
83
+ Verifies
84
+ --------
85
+ - Accepts valid integer values for retention_months.
86
+ - Invalid values raise `OrionisIntegrityException`.
62
87
  """
63
88
  # Test valid values
64
89
  try:
@@ -81,6 +106,11 @@ class TestConfigMonthly(TestCase):
81
106
  async def testWhitespaceHandling(self):
82
107
  """
83
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.
84
114
  """
85
115
  monthly = Monthly(path=" logs/app.log ", level=" debug ")
86
116
  self.assertEqual(monthly.path, " logs/app.log ")
@@ -89,6 +119,10 @@ class TestConfigMonthly(TestCase):
89
119
  async def testToDictMethod(self):
90
120
  """
91
121
  Test that toDict returns proper dictionary representation.
122
+
123
+ Verifies
124
+ --------
125
+ - Output is a dictionary with correct keys and values.
92
126
  """
93
127
  monthly = Monthly()
94
128
  monthly_dict = monthly.toDict()
@@ -100,6 +134,10 @@ class TestConfigMonthly(TestCase):
100
134
  async def testCustomValuesToDict(self):
101
135
  """
102
136
  Test that custom values are properly included in dictionary.
137
+
138
+ Verifies
139
+ --------
140
+ - Custom path, level, and retention_months are reflected in the output dictionary.
103
141
  """
104
142
  custom_monthly = Monthly(
105
143
  path="custom/logs/app.log",
@@ -114,6 +152,10 @@ class TestConfigMonthly(TestCase):
114
152
  async def testHashability(self):
115
153
  """
116
154
  Test that Monthly maintains hashability due to unsafe_hash=True.
155
+
156
+ Verifies
157
+ --------
158
+ - Monthly instances can be added to a set and compared by value.
117
159
  """
118
160
  monthly1 = Monthly()
119
161
  monthly2 = Monthly()
@@ -128,6 +170,10 @@ class TestConfigMonthly(TestCase):
128
170
  async def testKwOnlyInitialization(self):
129
171
  """
130
172
  Test that Monthly enforces keyword-only initialization.
173
+
174
+ Verifies
175
+ --------
176
+ - Positional arguments raise TypeError.
131
177
  """
132
178
  with self.assertRaises(TypeError):
133
179
  Monthly("path.log", "info", 4)