orionis 0.312.0__py3-none-any.whl → 0.314.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.
@@ -140,6 +140,7 @@ class UnitTest(IUnitTest):
140
140
 
141
141
  def configure(
142
142
  self,
143
+ *,
143
144
  verbosity: int = None,
144
145
  execution_mode: str | ExecutionMode = None,
145
146
  max_workers: int = None,
@@ -210,6 +211,7 @@ class UnitTest(IUnitTest):
210
211
 
211
212
  def discoverTestsInFolder(
212
213
  self,
214
+ *,
213
215
  folder_path: str,
214
216
  base_path: str = "tests",
215
217
  pattern: str = "test_*.py",
@@ -281,7 +283,7 @@ class UnitTest(IUnitTest):
281
283
  except Exception as e:
282
284
  raise OrionisTestValueError(f"Unexpected error discovering tests: {str(e)}")
283
285
 
284
- def discoverTestsInModule(self, module_name: str, test_name_pattern: Optional[str] = None) -> 'UnitTest':
286
+ def discoverTestsInModule(self, *, module_name: str, test_name_pattern: Optional[str] = None) -> 'UnitTest':
285
287
  """
286
288
  Discovers and loads tests from a specified module, optionally filtering by a test name pattern, and adds them to the test suite.
287
289
 
@@ -1129,15 +1131,22 @@ class UnitTest(IUnitTest):
1129
1131
  and ensuring that each test appears only once in the resulting list.
1130
1132
  """
1131
1133
  tests = []
1132
- seen = set()
1134
+ seen_ids = set()
1133
1135
 
1134
1136
  def _flatten(item):
1135
1137
  if isinstance(item, unittest.TestSuite):
1136
1138
  for sub_item in item:
1137
1139
  _flatten(sub_item)
1138
- elif item not in seen:
1139
- seen.add(item)
1140
- tests.append(item)
1140
+ elif hasattr(item, "id"):
1141
+ test_id = item.id()
1142
+ parts = test_id.split('.')
1143
+ if len(parts) >= 2:
1144
+ short_id = '.'.join(parts[-2:])
1145
+ else:
1146
+ short_id = test_id
1147
+ if short_id not in seen_ids:
1148
+ seen_ids.add(short_id)
1149
+ tests.append(item)
1141
1150
 
1142
1151
  _flatten(suite)
1143
1152
  return tests
@@ -1404,8 +1413,6 @@ class UnitTest(IUnitTest):
1404
1413
  """
1405
1414
  if self.__output_buffer:
1406
1415
  print(self.__output_buffer)
1407
- else:
1408
- print("No output buffer available.")
1409
1416
 
1410
1417
  def getErrorBuffer(self) -> int:
1411
1418
  """
@@ -1424,6 +1431,4 @@ class UnitTest(IUnitTest):
1424
1431
  This method retrieves the error buffer and prints its contents using the rich console.
1425
1432
  """
1426
1433
  if self.__error_buffer:
1427
- print(self.__error_buffer)
1428
- else:
1429
- print("No error buffer available.")
1434
+ print(self.__error_buffer)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: orionis
3
- Version: 0.312.0
3
+ Version: 0.314.0
4
4
  Summary: Orionis Framework – Elegant, Fast, and Powerful.
5
5
  Home-page: https://github.com/orionis-framework/framework
6
6
  Author: Raul Mauricio Uñate Castro
@@ -135,11 +135,11 @@ orionis/console/output/console.py,sha256=TE_Hl720ADd82dbERFSWhkoQRukDQZmETSw4nkw
135
135
  orionis/console/output/executor.py,sha256=bdvkzW2-buy0BPpy2r5qUGrRFW2Ay6k-5rSeHb0gQ3o,3352
136
136
  orionis/console/output/progress_bar.py,sha256=vFy582z6VJS46LV6tuyrmr9qvdVeTEtw3hyNcEHezeg,3088
137
137
  orionis/console/output/styles.py,sha256=6a4oQCOBOKMh2ARdeq5GlIskJ3wjiylYmh66tUKKmpQ,4053
138
- orionis/container/container.py,sha256=eP2YEf2UdllDFbfPPB4ILcdVQBd5kgHyWZkdttfsp1s,928
138
+ orionis/container/container.py,sha256=bUpUV_4_Zi5vpj7R86glNVB0iLQk67qXJAe1uEfhgKM,19474
139
139
  orionis/container/enums/lifetimes.py,sha256=RqQmugMIB1Ev_j_vFLcWorndm-to7xg4stQ7yKFDdDw,190
140
- orionis/container/exceptions/container_exception.py,sha256=cmoiDR2LvQ4AnxxZL-F3JdeI18ux7CzKmsCki98DAEk,585
141
- orionis/container/exceptions/type_error_exception.py,sha256=M7I64T5wBtHzLRyvrdP4dEzF2N3UzbOAnQmpyKy9aWo,547
142
- orionis/container/exceptions/value_exception.py,sha256=FSFsoG_piErEs-OOCtDrdDY02bPIOdNy4-rbJ8qPNHg,565
140
+ orionis/container/exceptions/container_exception.py,sha256=goTDEwC70xTMD2qppN8KV-xyR0Nps218OD4D1LZ2-3s,470
141
+ orionis/container/exceptions/type_error_exception.py,sha256=cYuvoXVOgRYj3tZPfK341aUERkf33-buOiI2eXxcrAw,470
142
+ orionis/container/exceptions/value_exception.py,sha256=hjY0YEusoL3DurME1ornxvIv1wyGaf6tBggLFlGHblo,472
143
143
  orionis/foundation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
144
144
  orionis/foundation/config/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
145
145
  orionis/foundation/config/startup.py,sha256=JKAH2ZRhlAZgkD2w11LR1-TVktfjSH9cHo3PsZXOLrg,8275
@@ -231,7 +231,7 @@ orionis/foundation/contracts/config.py,sha256=Rpz6U6t8OXHO9JJKSTnCimytXE-tfCB-1i
231
231
  orionis/foundation/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
232
232
  orionis/foundation/exceptions/integrity.py,sha256=mc4pL1UMoYRHEmphnpW2oGk5URhu7DJRREyzHaV-cs8,472
233
233
  orionis/metadata/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
234
- orionis/metadata/framework.py,sha256=OY1y-roZUBYR9Du8KyC-jHXB-GPu8Sjj9j-gB99J0hQ,4960
234
+ orionis/metadata/framework.py,sha256=TeS7Xb6-ikiXXQ64K1gd_KmswDCfsqNDRvkEd0sR0ZQ,4960
235
235
  orionis/metadata/package.py,sha256=tqLfBRo-w1j_GN4xvzUNFyweWYFS-qhSgAEc-AmCH1M,5452
236
236
  orionis/patterns/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
237
237
  orionis/patterns/singleton/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -254,11 +254,11 @@ orionis/services/environment/exceptions/__init__.py,sha256=47DEQpj8HBSa-_TImW-5J
254
254
  orionis/services/environment/exceptions/environment_value_error.py,sha256=Pe1qNHRrM9T0AzESN284CzA3GQYxzokfXPMOVqOTlyQ,475
255
255
  orionis/services/environment/exceptions/environment_value_exception.py,sha256=NnxWmgoSca7LXi7GLDa95HSBPKotFfy8u729d1OAmCc,479
256
256
  orionis/services/introspection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
257
- orionis/services/introspection/reflection.py,sha256=AI5ZMv9kHCLOQe9lL_G7wAeY3cPLKZ1FMYqIhU0yS-M,2972
257
+ orionis/services/introspection/reflection.py,sha256=6z4VkDICohMIkm9jEd7nmFABwVuU7SBoTFaH3tq4PGk,10897
258
258
  orionis/services/introspection/abstract/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
259
- orionis/services/introspection/abstract/reflection_abstract.py,sha256=O8fK2a7X82VOK4Pt2Zv6Mt0wsxezLFTyb1JVu9ApCVc,43327
259
+ orionis/services/introspection/abstract/reflection_abstract.py,sha256=SPK2X11VvGORxxPOYloaD6hPAvky--obRU4CO1DE4zM,43865
260
260
  orionis/services/introspection/concretes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
261
- orionis/services/introspection/concretes/reflection_concrete.py,sha256=dhZHzMcGNXzxinWOf8gdeD1h2bUgqrLgw00qdAcor2U,49755
261
+ orionis/services/introspection/concretes/reflection_concrete.py,sha256=1GxD-y8LPGL6kI4Y3XbeLcFjR5Y8cOqbVEPCtPnsuYA,50982
262
262
  orionis/services/introspection/contracts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
263
263
  orionis/services/introspection/contracts/reflect_dependencies.py,sha256=5fdImZarC1ixoFM-1JSBx28RvYbY3GGZhDGjar7cvHc,1771
264
264
  orionis/services/introspection/contracts/reflection_abstract.py,sha256=-ugpFcAkGTlk0Md5ft8NrvupnlfVji8QZjGYqWBxqeY,22370
@@ -276,7 +276,7 @@ orionis/services/introspection/exceptions/reflection_attribute_error.py,sha256=_
276
276
  orionis/services/introspection/exceptions/reflection_type_error.py,sha256=73DB8JoTbxd7LNMnZKXf4jJ8OzLyC0HPXgDo5pffkYY,466
277
277
  orionis/services/introspection/exceptions/reflection_value_error.py,sha256=ywO_cwawEmB22uP3i4ofsZytO9QTbvy7axm9NzEfHr4,467
278
278
  orionis/services/introspection/instances/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
279
- orionis/services/introspection/instances/reflection_instance.py,sha256=89sgsV059H5CeoIuJQBeARujNwl6uXwqxyy5HBfjKV4,51929
279
+ orionis/services/introspection/instances/reflection_instance.py,sha256=DrPrzdm7FbnUj6h6970hJOyFfit-OpWskZ4FnxJMz6k,54053
280
280
  orionis/services/introspection/modules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
281
281
  orionis/services/introspection/modules/reflection_module.py,sha256=1QB_853_ct5ehDNSxNQaaJDCeY9eXciXJwRYkNHgYd4,15632
282
282
  orionis/services/parsers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -335,10 +335,10 @@ orionis/test/logs/history.py,sha256=eAEPWpubs1fFzL-0o8K82hd2lC0S98VOu1AEblCmjYI,
335
335
  orionis/test/output/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
336
336
  orionis/test/output/dumper.py,sha256=q1_S5AYMce01ukPkEJ73gQT7gyLBK5XA1NyOeVINQMI,4280
337
337
  orionis/test/suite/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
338
- orionis/test/suite/test_unit.py,sha256=5UTdCYmD_Yz8asaBF54RHOx0kjwjLjEhkyPDoDIxk-k,57049
338
+ orionis/test/suite/test_unit.py,sha256=wKqbLmkz1t0ilhLU6vz9ThCfURTM5hPQBLFTDC_vcII,57254
339
339
  orionis/test/view/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
340
340
  orionis/test/view/render.py,sha256=jXZkbITBknbUwm_mD8bcTiwLDvsFkrO9qrf0ZgPwqxc,4903
341
- orionis-0.312.0.dist-info/licenses/LICENCE,sha256=-_4cF2EBKuYVS_SQpy1uapq0oJPUU1vl_RUWSy2jJTo,1111
341
+ orionis-0.314.0.dist-info/licenses/LICENCE,sha256=-_4cF2EBKuYVS_SQpy1uapq0oJPUU1vl_RUWSy2jJTo,1111
342
342
  tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
343
343
  tests/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
344
344
  tests/example/test_example.py,sha256=kvWgiW3ADEZf718dGsMPtDh_rmOSx1ypEInKm7_6ZPQ,601
@@ -407,6 +407,7 @@ tests/services/asynchrony/test_services_asynchrony_coroutine.py,sha256=azlDv29Q9
407
407
  tests/services/environment/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
408
408
  tests/services/environment/test_services_environment.py,sha256=fdkjwbY-aDEA1FT-9vBT5ihwaCdg_-UgAx--kQXFPGA,3745
409
409
  tests/services/inspection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
410
+ tests/services/inspection/test_reflection.py,sha256=ZApQeaDxYLsrfGN6UqEDPbyNzocMV9CURflQ35YMfqk,13678
410
411
  tests/services/inspection/dependencies/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
411
412
  tests/services/inspection/dependencies/test_reflect_dependencies.py,sha256=z0C9KkhV27Y7jKpLSCN9XCmHbjJDCPbBb7NkRFs3oMI,5803
412
413
  tests/services/inspection/dependencies/mocks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -436,9 +437,9 @@ tests/support/wrapper/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
436
437
  tests/support/wrapper/test_services_wrapper_docdict.py,sha256=yeVwl-VcwkWSQYyxZu3qfqT7YtP8LIEJgHo2ejzISh0,4984
437
438
  tests/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
438
439
  tests/testing/test_testing_result.py,sha256=MrGK3ZimedL0b5Ydu69Dg8Iul017AzLTm7VPxpXlpfU,4315
439
- tests/testing/test_testing_unit.py,sha256=A6QkiOkP7GPC1Szh_GqsrV7GxjWjK8cIwFez6YfrzmM,7683
440
- orionis-0.312.0.dist-info/METADATA,sha256=9Js6d3O7wPFOdIXfLXomApm1mBjD6r556KQQEejCwZM,4772
441
- orionis-0.312.0.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
442
- orionis-0.312.0.dist-info/top_level.txt,sha256=2bdoHgyGZhOtLAXS6Om8OCTmL24dUMC_L1quMe_ETbk,14
443
- orionis-0.312.0.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
444
- orionis-0.312.0.dist-info/RECORD,,
440
+ tests/testing/test_testing_unit.py,sha256=9flen4fNMSFWrZUzGyUq8Sd0wwRlj1BgnrRyJVn_uQs,7695
441
+ orionis-0.314.0.dist-info/METADATA,sha256=00zT_BZNttTEU5W9ufDdJNoXUkL4eCAR32wyIVjRrz0,4772
442
+ orionis-0.314.0.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
443
+ orionis-0.314.0.dist-info/top_level.txt,sha256=2bdoHgyGZhOtLAXS6Om8OCTmL24dUMC_L1quMe_ETbk,14
444
+ orionis-0.314.0.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
445
+ orionis-0.314.0.dist-info/RECORD,,
@@ -0,0 +1,462 @@
1
+ from orionis.services.introspection.reflection import Reflection
2
+ from orionis.unittesting import TestCase
3
+ import sys
4
+ import inspect
5
+ import abc
6
+
7
+ class TestServiceReflectionAbstract(TestCase):
8
+
9
+ async def testIsAbstract(self):
10
+ """
11
+ Test Reflection.isAbstract for abstract and concrete classes.
12
+
13
+ Parameters
14
+ ----------
15
+ None
16
+
17
+ Tests
18
+ -----
19
+ - DummyAbstract: An abstract class using abc.ABCMeta with an abstract method.
20
+ - DummyConcrete: A regular concrete class.
21
+
22
+ Returns
23
+ -------
24
+ None
25
+
26
+ Asserts
27
+ -------
28
+ - Reflection.isAbstract(DummyAbstract) returns True.
29
+ - Reflection.isAbstract(DummyConcrete) returns False.
30
+ """
31
+ class DummyAbstract(metaclass=abc.ABCMeta):
32
+ @abc.abstractmethod
33
+ def foo(self):
34
+ pass
35
+
36
+ class DummyConcrete:
37
+ def bar(self):
38
+ return 42
39
+
40
+ self.assertTrue(Reflection.isAbstract(DummyAbstract))
41
+ self.assertFalse(Reflection.isAbstract(DummyConcrete))
42
+
43
+ async def testIsAsyncGen(self):
44
+ """
45
+ Test Reflection.isAsyncGen for correct identification of asynchronous generators.
46
+
47
+ Notes
48
+ -----
49
+ - The asynchronous generator is defined using `async def` and `yield`.
50
+ - The regular generator is defined using `def` and `yield`.
51
+
52
+ Returns
53
+ -------
54
+ None
55
+
56
+ Asserts
57
+ -------
58
+ - Reflection.isAsyncGen(agen) is True.
59
+ - Reflection.isAsyncGen(dummy_generator()) is False.
60
+ """
61
+ async def dummy_asyncgen():
62
+ yield 1
63
+
64
+ def dummy_generator():
65
+ yield 1
66
+
67
+ agen = dummy_asyncgen()
68
+ self.assertTrue(Reflection.isAsyncGen(agen))
69
+ self.assertFalse(Reflection.isAsyncGen(dummy_generator()))
70
+
71
+ async def testIsAsyncGenFunction(self):
72
+ """
73
+ Test Reflection.isAsyncGenFunction for correct identification of async generator functions.
74
+
75
+ Returns
76
+ -------
77
+ None
78
+
79
+ Asserts
80
+ -------
81
+ - Reflection.isAsyncGenFunction(dummy_asyncgen) returns True.
82
+ - Reflection.isAsyncGenFunction(dummy_generator) returns False.
83
+ """
84
+ async def dummy_asyncgen():
85
+ yield 1
86
+
87
+ def dummy_generator():
88
+ yield 1
89
+
90
+ self.assertTrue(Reflection.isAsyncGenFunction(dummy_asyncgen))
91
+ self.assertFalse(Reflection.isAsyncGenFunction(dummy_generator))
92
+
93
+ async def testIsAwaitable(self):
94
+ """
95
+ Test Reflection.isAwaitable to verify correct identification of awaitable objects.
96
+
97
+ Returns
98
+ -------
99
+ None
100
+
101
+ Asserts
102
+ -------
103
+ - An async coroutine object is recognized as awaitable.
104
+ - A non-awaitable object (e.g., an integer) is not recognized as awaitable.
105
+ """
106
+ async def dummy_coroutine():
107
+ pass
108
+
109
+ coro = dummy_coroutine()
110
+ self.assertTrue(Reflection.isAwaitable(coro))
111
+ self.assertFalse(Reflection.isAwaitable(42))
112
+
113
+ async def testIsBuiltin(self):
114
+ """
115
+ Test Reflection.isBuiltin to verify correct identification of built-in functions.
116
+
117
+ Returns
118
+ -------
119
+ None
120
+
121
+ Asserts
122
+ -------
123
+ - The built-in function `len` is recognized as built-in.
124
+ - A user-defined function is not recognized as built-in.
125
+ """
126
+ def dummy_function():
127
+ pass
128
+
129
+ self.assertTrue(Reflection.isBuiltin(len))
130
+ self.assertFalse(Reflection.isBuiltin(dummy_function))
131
+
132
+ async def testIsClass(self):
133
+ """
134
+ Test Reflection.isClass to verify correct identification of classes and non-class objects.
135
+
136
+ Returns
137
+ -------
138
+ None
139
+
140
+ Asserts
141
+ -------
142
+ - Reflection.isClass returns True for a class.
143
+ - Reflection.isClass returns False for a function.
144
+ """
145
+ class DummyConcrete:
146
+ def bar(self):
147
+ return 42
148
+
149
+ def dummy_function():
150
+ pass
151
+
152
+ self.assertTrue(Reflection.isClass(DummyConcrete))
153
+ self.assertFalse(Reflection.isClass(dummy_function))
154
+
155
+ async def testIsCode(self):
156
+ """
157
+ Test Reflection.isCode to verify correct identification of code objects.
158
+
159
+ Returns
160
+ -------
161
+ None
162
+
163
+ Asserts
164
+ -------
165
+ - Passing a function's __code__ attribute returns True.
166
+ - Passing the function itself returns False.
167
+ """
168
+ def dummy_function():
169
+ pass
170
+
171
+ self.assertTrue(Reflection.isCode(dummy_function.__code__))
172
+ self.assertFalse(Reflection.isCode(dummy_function))
173
+
174
+ async def testIsCoroutine(self):
175
+ """
176
+ Test Reflection.isCoroutine to ensure correct identification of coroutine objects.
177
+
178
+ Returns
179
+ -------
180
+ None
181
+
182
+ Asserts
183
+ -------
184
+ - Reflection.isCoroutine returns True for a coroutine object.
185
+ - Reflection.isCoroutine returns False for a regular function.
186
+ """
187
+ async def dummy_coroutine():
188
+ pass
189
+
190
+ def dummy_function():
191
+ pass
192
+
193
+ coro = dummy_coroutine()
194
+ self.assertTrue(Reflection.isCoroutine(coro))
195
+ self.assertFalse(Reflection.isCoroutine(dummy_function))
196
+
197
+ async def testIsCoroutineFunction(self):
198
+ """
199
+ Test Reflection.isCoroutineFunction to verify correct identification of coroutine functions.
200
+
201
+ Returns
202
+ -------
203
+ None
204
+
205
+ Asserts
206
+ -------
207
+ - Reflection.isCoroutineFunction(dummy_coroutine) returns True.
208
+ - Reflection.isCoroutineFunction(dummy_function) returns False.
209
+ """
210
+ async def dummy_coroutine():
211
+ pass
212
+
213
+ def dummy_function():
214
+ pass
215
+
216
+ self.assertTrue(Reflection.isCoroutineFunction(dummy_coroutine))
217
+ self.assertFalse(Reflection.isCoroutineFunction(dummy_function))
218
+
219
+ async def testIsDataDescriptor(self):
220
+ """
221
+ Test Reflection.isDataDescriptor to verify correct identification of data descriptors.
222
+
223
+ Returns
224
+ -------
225
+ None
226
+
227
+ Asserts
228
+ -------
229
+ - A property object is recognized as a data descriptor.
230
+ - A non-descriptor object (such as an integer) is not.
231
+ """
232
+ class X:
233
+ @property
234
+ def foo(self): return 1
235
+
236
+ self.assertTrue(Reflection.isDataDescriptor(X.__dict__['foo']))
237
+ self.assertFalse(Reflection.isDataDescriptor(42))
238
+
239
+ async def testIsFrame(self):
240
+ """
241
+ Test Reflection.isFrame to verify correct identification of frame objects.
242
+
243
+ Returns
244
+ -------
245
+ None
246
+
247
+ Asserts
248
+ -------
249
+ - Reflection.isFrame returns True for a valid frame object.
250
+ - Reflection.isFrame returns False for a non-frame object.
251
+ """
252
+ frame = inspect.currentframe()
253
+ self.assertTrue(Reflection.isFrame(frame))
254
+ self.assertFalse(Reflection.isFrame(42))
255
+
256
+ async def testIsFunction(self):
257
+ """
258
+ Test Reflection.isFunction to verify correct identification of functions.
259
+
260
+ Returns
261
+ -------
262
+ None
263
+
264
+ Asserts
265
+ -------
266
+ - A standalone function is correctly identified as a function.
267
+ - An unbound method is not identified as a function.
268
+ """
269
+ def dummy_function():
270
+ pass
271
+
272
+ class DummyConcrete:
273
+ def bar(self):
274
+ return 42
275
+
276
+ self.assertTrue(Reflection.isFunction(dummy_function))
277
+ # Unbound methods in Python 3 are just functions, so this should be True
278
+ self.assertTrue(Reflection.isFunction(DummyConcrete.bar))
279
+
280
+ async def testIsGenerator(self):
281
+ """
282
+ Test Reflection.isGenerator to verify correct identification of generator objects.
283
+
284
+ Returns
285
+ -------
286
+ None
287
+
288
+ Asserts
289
+ -------
290
+ - Reflection.isGenerator returns True for a generator object.
291
+ - Reflection.isGenerator returns False for a regular function.
292
+ """
293
+ def dummy_generator():
294
+ yield 1
295
+
296
+ def dummy_function():
297
+ pass
298
+
299
+ gen = dummy_generator()
300
+ self.assertTrue(Reflection.isGenerator(gen))
301
+ self.assertFalse(Reflection.isGenerator(dummy_function))
302
+
303
+ async def testIsGeneratorFunction(self):
304
+ """
305
+ Test Reflection.isGeneratorFunction to verify correct identification of generator functions.
306
+
307
+ Returns
308
+ -------
309
+ None
310
+
311
+ Asserts
312
+ -------
313
+ - Reflection.isGeneratorFunction(dummy_generator) returns True.
314
+ - Reflection.isGeneratorFunction(dummy_function) returns False.
315
+ """
316
+ def dummy_generator():
317
+ yield 1
318
+
319
+ def dummy_function():
320
+ pass
321
+
322
+ self.assertTrue(Reflection.isGeneratorFunction(dummy_generator))
323
+ self.assertFalse(Reflection.isGeneratorFunction(dummy_function))
324
+
325
+ async def testIsGetSetDescriptor(self):
326
+ """
327
+ Test Reflection.isGetSetDescriptor to verify correct identification of get-set descriptors.
328
+
329
+ Returns
330
+ -------
331
+ None
332
+
333
+ Asserts
334
+ -------
335
+ - Reflection.isGetSetDescriptor returns True for a known get-set descriptor.
336
+ - Reflection.isGetSetDescriptor returns False for a non-descriptor object.
337
+ """
338
+ self.assertTrue(Reflection.isGetSetDescriptor(type.__dict__['__dict__']))
339
+ self.assertFalse(Reflection.isGetSetDescriptor(42))
340
+
341
+ async def testIsMemberDescriptor(self):
342
+ """
343
+ Test Reflection.isMemberDescriptor to verify correct identification of member descriptors.
344
+
345
+ Returns
346
+ -------
347
+ None
348
+
349
+ Asserts
350
+ -------
351
+ - type.__dict__['__weakref__'] is recognized as a member descriptor.
352
+ - An integer is not recognized as a member descriptor.
353
+ """
354
+ # Use an alternative member descriptor: use a slot from a new-style class
355
+ class Y:
356
+ __slots__ = ('foo',)
357
+ self.assertTrue(Reflection.isMemberDescriptor(Y.__dict__['foo']))
358
+ self.assertFalse(Reflection.isMemberDescriptor(42))
359
+ self.assertFalse(Reflection.isMemberDescriptor(42))
360
+
361
+ async def testIsMethod(self):
362
+ """
363
+ Test Reflection.isMethod to verify correct identification of methods.
364
+
365
+ Returns
366
+ -------
367
+ None
368
+
369
+ Asserts
370
+ -------
371
+ - Reflection.isMethod returns True for a class method.
372
+ - Reflection.isMethod returns False for a standalone function.
373
+ """
374
+ class DummyConcrete:
375
+ def bar(self):
376
+ return 42
377
+
378
+ obj = DummyConcrete()
379
+ def dummy_function():
380
+ pass
381
+
382
+ self.assertTrue(Reflection.isMethod(obj.bar))
383
+ self.assertFalse(Reflection.isMethod(dummy_function))
384
+
385
+ async def testIsMethodDescriptor(self):
386
+ """
387
+ Test Reflection.isMethodDescriptor to verify correct identification of method descriptors.
388
+
389
+ Returns
390
+ -------
391
+ None
392
+
393
+ Asserts
394
+ -------
395
+ - Reflection.isMethodDescriptor(str.upper) returns True.
396
+ - Reflection.isMethodDescriptor(dummy_function) returns False.
397
+ """
398
+ def dummy_function():
399
+ pass
400
+
401
+ self.assertTrue(Reflection.isMethodDescriptor(str.upper))
402
+ self.assertFalse(Reflection.isMethodDescriptor(dummy_function))
403
+
404
+ async def testIsModule(self):
405
+ """
406
+ Test Reflection.isModule to verify correct identification of module objects.
407
+
408
+ Returns
409
+ -------
410
+ None
411
+
412
+ Asserts
413
+ -------
414
+ - Reflection.isModule returns True for a module (e.g., sys).
415
+ - Reflection.isModule returns False for a non-module (e.g., a function).
416
+ """
417
+ def dummy_function():
418
+ pass
419
+
420
+ self.assertTrue(Reflection.isModule(sys))
421
+ self.assertFalse(Reflection.isModule(dummy_function))
422
+
423
+ async def testIsRoutine(self):
424
+ """
425
+ Test Reflection.isRoutine to verify correct identification of routine objects.
426
+
427
+ Returns
428
+ -------
429
+ None
430
+
431
+ Asserts
432
+ -------
433
+ - A user-defined function is recognized as a routine.
434
+ - A built-in function is recognized as a routine.
435
+ - A non-routine object is not recognized as a routine.
436
+ """
437
+ def dummy_function():
438
+ pass
439
+
440
+ self.assertTrue(Reflection.isRoutine(dummy_function))
441
+ self.assertTrue(Reflection.isRoutine(len))
442
+ self.assertFalse(Reflection.isRoutine(42))
443
+
444
+ async def testIsTraceback(self):
445
+ """
446
+ Test Reflection.isTraceback to verify correct identification of traceback objects.
447
+
448
+ Returns
449
+ -------
450
+ None
451
+
452
+ Asserts
453
+ -------
454
+ - Reflection.isTraceback returns True for a traceback object.
455
+ - Reflection.isTraceback returns False for a non-traceback object.
456
+ """
457
+ try:
458
+ raise Exception("test")
459
+ except Exception:
460
+ tb = sys.exc_info()[2]
461
+ self.assertTrue(Reflection.isTraceback(tb))
462
+ self.assertFalse(Reflection.isTraceback(42))
@@ -76,7 +76,7 @@ class TestTestingUnit(TestCase):
76
76
  unit_test = UnitTest()
77
77
  with patch.object(unit_test.loader, 'loadTestsFromName') as mock_load:
78
78
  mock_load.return_value = StandardTestSuite()
79
- result = unit_test.discoverTestsInModule('test_module')
79
+ result = unit_test.discoverTestsInModule(module_name='test_module')
80
80
 
81
81
  mock_load.assert_called_once_with('test_module')
82
82
  self.assertEqual(result, unit_test)