provide-testkit 0.0.0.dev0__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 (66) hide show
  1. provide/__init__.py +3 -0
  2. provide/testkit/__init__.py +248 -0
  3. provide/testkit/archive/__init__.py +24 -0
  4. provide/testkit/archive/fixtures.py +217 -0
  5. provide/testkit/cli.py +229 -0
  6. provide/testkit/common/__init__.py +32 -0
  7. provide/testkit/common/fixtures.py +234 -0
  8. provide/testkit/crypto.py +163 -0
  9. provide/testkit/environment.py +79 -0
  10. provide/testkit/file/__init__.py +40 -0
  11. provide/testkit/file/content_fixtures.py +275 -0
  12. provide/testkit/file/directory_fixtures.py +105 -0
  13. provide/testkit/file/fixtures.py +49 -0
  14. provide/testkit/file/special_fixtures.py +141 -0
  15. provide/testkit/fixtures.py +52 -0
  16. provide/testkit/harness.py +122 -0
  17. provide/testkit/hub.py +22 -0
  18. provide/testkit/logger/__init__.py +39 -0
  19. provide/testkit/logger/hooks.py +100 -0
  20. provide/testkit/logger/reset.py +230 -0
  21. provide/testkit/main.py +22 -0
  22. provide/testkit/mocking/__init__.py +46 -0
  23. provide/testkit/mocking/fixtures.py +340 -0
  24. provide/testkit/process/__init__.py +48 -0
  25. provide/testkit/process/async_fixtures.py +410 -0
  26. provide/testkit/process/fixtures.py +54 -0
  27. provide/testkit/process/subprocess_fixtures.py +208 -0
  28. provide/testkit/quality/__init__.py +101 -0
  29. provide/testkit/quality/artifacts.py +360 -0
  30. provide/testkit/quality/base.py +158 -0
  31. provide/testkit/quality/cli.py +394 -0
  32. provide/testkit/quality/complexity/__init__.py +30 -0
  33. provide/testkit/quality/complexity/analyzer.py +392 -0
  34. provide/testkit/quality/complexity/fixture.py +196 -0
  35. provide/testkit/quality/coverage/__init__.py +36 -0
  36. provide/testkit/quality/coverage/fixture.py +236 -0
  37. provide/testkit/quality/coverage/reporter.py +150 -0
  38. provide/testkit/quality/coverage/tracker.py +313 -0
  39. provide/testkit/quality/decorators.py +380 -0
  40. provide/testkit/quality/documentation/__init__.py +29 -0
  41. provide/testkit/quality/documentation/checker.py +361 -0
  42. provide/testkit/quality/documentation/fixture.py +187 -0
  43. provide/testkit/quality/profiling/__init__.py +30 -0
  44. provide/testkit/quality/profiling/fixture.py +332 -0
  45. provide/testkit/quality/profiling/profiler.py +428 -0
  46. provide/testkit/quality/report.py +266 -0
  47. provide/testkit/quality/runner.py +319 -0
  48. provide/testkit/quality/security/__init__.py +29 -0
  49. provide/testkit/quality/security/fixture.py +196 -0
  50. provide/testkit/quality/security/scanner.py +338 -0
  51. provide/testkit/streams.py +54 -0
  52. provide/testkit/threading/__init__.py +38 -0
  53. provide/testkit/threading/basic_fixtures.py +103 -0
  54. provide/testkit/threading/data_fixtures.py +101 -0
  55. provide/testkit/threading/execution_fixtures.py +268 -0
  56. provide/testkit/threading/fixtures.py +50 -0
  57. provide/testkit/threading/sync_fixtures.py +98 -0
  58. provide/testkit/time/__init__.py +32 -0
  59. provide/testkit/time/fixtures.py +416 -0
  60. provide/testkit/transport/__init__.py +30 -0
  61. provide/testkit/transport/fixtures.py +278 -0
  62. provide_testkit-0.0.0.dev0.dist-info/METADATA +145 -0
  63. provide_testkit-0.0.0.dev0.dist-info/RECORD +66 -0
  64. provide_testkit-0.0.0.dev0.dist-info/WHEEL +5 -0
  65. provide_testkit-0.0.0.dev0.dist-info/entry_points.txt +2 -0
  66. provide_testkit-0.0.0.dev0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,340 @@
1
+ """
2
+ Mocking Fixtures and Utilities.
3
+
4
+ Standardized mocking patterns and fixtures for the provide-io ecosystem.
5
+ Reduces boilerplate and ensures consistent mocking across all tests.
6
+ """
7
+
8
+ from typing import Any
9
+ from unittest.mock import ANY, AsyncMock, MagicMock, Mock, PropertyMock, call, patch
10
+
11
+ import pytest
12
+
13
+
14
+ @pytest.fixture
15
+ def mock_factory():
16
+ """
17
+ Factory for creating configured mock objects.
18
+
19
+ Returns:
20
+ Function that creates mock objects with common configurations.
21
+ """
22
+
23
+ def _create_mock(name: str | None = None, **kwargs) -> Mock:
24
+ """
25
+ Create a mock with standard configuration.
26
+
27
+ Args:
28
+ name: Optional name for the mock
29
+ **kwargs: Additional mock configuration
30
+
31
+ Returns:
32
+ Configured Mock object
33
+ """
34
+ defaults = {
35
+ "spec_set": True if "spec" in kwargs else False,
36
+ }
37
+ defaults.update(kwargs)
38
+
39
+ mock = Mock(name=name, **defaults)
40
+ return mock
41
+
42
+ return _create_mock
43
+
44
+
45
+ @pytest.fixture
46
+ def magic_mock_factory():
47
+ """
48
+ Factory for creating MagicMock objects.
49
+
50
+ Returns:
51
+ Function that creates MagicMock objects with common configurations.
52
+ """
53
+
54
+ def _create_magic_mock(name: str | None = None, **kwargs) -> MagicMock:
55
+ """
56
+ Create a MagicMock with standard configuration.
57
+
58
+ Args:
59
+ name: Optional name for the mock
60
+ **kwargs: Additional mock configuration
61
+
62
+ Returns:
63
+ Configured MagicMock object
64
+ """
65
+ return MagicMock(name=name, **kwargs)
66
+
67
+ return _create_magic_mock
68
+
69
+
70
+ @pytest.fixture
71
+ def async_mock_factory():
72
+ """
73
+ Factory for creating AsyncMock objects.
74
+
75
+ Returns:
76
+ Function that creates AsyncMock objects with common configurations.
77
+ """
78
+
79
+ def _create_async_mock(
80
+ name: str | None = None, return_value: object = None, side_effect: object = None, **kwargs
81
+ ) -> AsyncMock:
82
+ """
83
+ Create an AsyncMock with standard configuration.
84
+
85
+ Args:
86
+ name: Optional name for the mock
87
+ return_value: Return value for the async mock
88
+ side_effect: Side effect for the async mock
89
+ **kwargs: Additional mock configuration
90
+
91
+ Returns:
92
+ Configured AsyncMock object
93
+ """
94
+ mock = AsyncMock(name=name, **kwargs)
95
+ if return_value is not None:
96
+ mock.return_value = return_value
97
+ if side_effect is not None:
98
+ mock.side_effect = side_effect
99
+ return mock
100
+
101
+ return _create_async_mock
102
+
103
+
104
+ @pytest.fixture
105
+ def property_mock_factory():
106
+ """
107
+ Factory for creating PropertyMock objects.
108
+
109
+ Returns:
110
+ Function that creates PropertyMock objects.
111
+ """
112
+
113
+ def _create_property_mock(return_value=None, side_effect=None, **kwargs) -> PropertyMock:
114
+ """
115
+ Create a PropertyMock.
116
+
117
+ Args:
118
+ return_value: Return value for the property
119
+ side_effect: Side effect for the property
120
+ **kwargs: Additional mock configuration
121
+
122
+ Returns:
123
+ Configured PropertyMock object
124
+ """
125
+ return PropertyMock(return_value=return_value, side_effect=side_effect, **kwargs)
126
+
127
+ return _create_property_mock
128
+
129
+
130
+ @pytest.fixture
131
+ def patch_fixture():
132
+ """
133
+ Fixture for patching objects with automatic cleanup.
134
+
135
+ Returns:
136
+ Function that patches objects and returns the mock.
137
+ """
138
+ patches = []
139
+
140
+ def _patch(target: str, **kwargs) -> Mock:
141
+ """
142
+ Patch a target with automatic cleanup.
143
+
144
+ Args:
145
+ target: The target to patch (module.Class.attribute)
146
+ **kwargs: Additional patch configuration
147
+
148
+ Returns:
149
+ The mock object
150
+ """
151
+ patcher = patch(target, **kwargs)
152
+ mock = patcher.start()
153
+ patches.append(patcher)
154
+ return mock
155
+
156
+ yield _patch
157
+
158
+ # Cleanup all patches
159
+ for patcher in patches:
160
+ patcher.stop()
161
+
162
+
163
+ @pytest.fixture
164
+ def patch_multiple_fixture():
165
+ """
166
+ Fixture for patching multiple objects at once.
167
+
168
+ Returns:
169
+ Function that patches multiple targets.
170
+ """
171
+ patches = []
172
+
173
+ def _patch_multiple(target_module: str, **kwargs) -> dict[str, Mock]:
174
+ """
175
+ Patch multiple attributes in a module.
176
+
177
+ Args:
178
+ target_module: The module to patch in
179
+ **kwargs: Mapping of attribute names to mock objects or DEFAULT
180
+
181
+ Returns:
182
+ Dict mapping attribute names to mock objects
183
+ """
184
+ from unittest.mock import patch as mock_patch
185
+
186
+ patcher = mock_patch.multiple(target_module, **kwargs)
187
+ mocks = patcher.start()
188
+ patches.append(patcher)
189
+ return mocks
190
+
191
+ yield _patch_multiple
192
+
193
+ # Cleanup all patches
194
+ for patcher in patches:
195
+ patcher.stop()
196
+
197
+
198
+ @pytest.fixture
199
+ def auto_patch():
200
+ """
201
+ Context manager for automatic patching with cleanup.
202
+
203
+ Returns:
204
+ Patch context manager class.
205
+ """
206
+
207
+ class AutoPatch:
208
+ def __init__(self):
209
+ self.patches = []
210
+
211
+ def object(self, target: Any, attribute: str, **kwargs) -> Mock:
212
+ """Patch an object's attribute."""
213
+ patcher = patch.object(target, attribute, **kwargs)
214
+ mock = patcher.start()
215
+ self.patches.append(patcher)
216
+ return mock
217
+
218
+ def dict(self, target: dict, values: dict, **kwargs) -> None:
219
+ """Patch a dictionary."""
220
+ patcher = patch.dict(target, values, **kwargs)
221
+ patcher.start()
222
+ self.patches.append(patcher)
223
+
224
+ def env(self, **env_vars) -> None:
225
+ """Patch environment variables."""
226
+ import os
227
+
228
+ patcher = patch.dict(os.environ, env_vars)
229
+ patcher.start()
230
+ self.patches.append(patcher)
231
+
232
+ def cleanup(self):
233
+ """Stop all patches."""
234
+ for patcher in self.patches:
235
+ patcher.stop()
236
+
237
+ patcher = AutoPatch()
238
+ yield patcher
239
+ patcher.cleanup()
240
+
241
+
242
+ @pytest.fixture
243
+ def mock_open_fixture():
244
+ """
245
+ Fixture for mocking file operations.
246
+
247
+ Returns:
248
+ Function that creates a mock for open().
249
+ """
250
+ from unittest.mock import mock_open
251
+
252
+ def _mock_open(read_data: str = None) -> Mock:
253
+ """
254
+ Create a mock for the open() builtin.
255
+
256
+ Args:
257
+ read_data: Optional data to return when reading
258
+
259
+ Returns:
260
+ Mock object for open()
261
+ """
262
+ return mock_open(read_data=read_data)
263
+
264
+ return _mock_open
265
+
266
+
267
+ @pytest.fixture
268
+ def spy_fixture():
269
+ """
270
+ Create a spy (mock that calls through to the original).
271
+
272
+ Returns:
273
+ Function that creates spy objects.
274
+ """
275
+
276
+ def _create_spy(obj: Any, method_name: str) -> Mock:
277
+ """
278
+ Create a spy on a method.
279
+
280
+ Args:
281
+ obj: The object to spy on
282
+ method_name: The method name to spy on
283
+
284
+ Returns:
285
+ Mock that wraps the original method
286
+ """
287
+ original = getattr(obj, method_name)
288
+ mock = Mock(wraps=original)
289
+ setattr(obj, method_name, mock)
290
+ return mock
291
+
292
+ return _create_spy
293
+
294
+
295
+ @pytest.fixture
296
+ def assert_mock_calls():
297
+ """
298
+ Helper for asserting mock calls with better error messages.
299
+
300
+ Returns:
301
+ Function for asserting mock calls.
302
+ """
303
+
304
+ def _assert_calls(mock: Mock, expected_calls: list, any_order: bool = False):
305
+ """
306
+ Assert that a mock was called with expected calls.
307
+
308
+ Args:
309
+ mock: The mock to check
310
+ expected_calls: List of expected call objects
311
+ any_order: Whether calls can be in any order
312
+ """
313
+ if any_order:
314
+ mock.assert_has_calls(expected_calls, any_order=True)
315
+ else:
316
+ mock.assert_has_calls(expected_calls)
317
+
318
+ return _assert_calls
319
+
320
+
321
+ # Re-export commonly used mock utilities
322
+ __all__ = [
323
+ "ANY",
324
+ "AsyncMock",
325
+ "MagicMock",
326
+ "Mock",
327
+ "PropertyMock",
328
+ "assert_mock_calls",
329
+ "async_mock_factory",
330
+ "auto_patch",
331
+ "call",
332
+ "magic_mock_factory",
333
+ "mock_factory",
334
+ "mock_open_fixture",
335
+ "patch",
336
+ "patch_fixture",
337
+ "patch_multiple_fixture",
338
+ "property_mock_factory",
339
+ "spy_fixture",
340
+ ]
@@ -0,0 +1,48 @@
1
+ """
2
+ Process and async testing fixtures for the provide-io ecosystem.
3
+
4
+ Standard fixtures for testing async code, subprocess operations, and
5
+ event loop management across any project that depends on provide.foundation.
6
+ """
7
+
8
+ from provide.testkit.process.fixtures import (
9
+ async_condition_waiter,
10
+ async_context_manager,
11
+ async_gather_helper,
12
+ async_iterator,
13
+ async_lock,
14
+ async_mock_server,
15
+ async_pipeline,
16
+ async_queue,
17
+ async_rate_limiter,
18
+ async_stream_reader,
19
+ async_subprocess,
20
+ async_task_group,
21
+ async_test_client,
22
+ async_timeout,
23
+ clean_event_loop,
24
+ event_loop_policy,
25
+ mock_async_process,
26
+ mock_async_sleep,
27
+ )
28
+
29
+ __all__ = [
30
+ "async_condition_waiter",
31
+ "async_context_manager",
32
+ "async_gather_helper",
33
+ "async_iterator",
34
+ "async_lock",
35
+ "async_mock_server",
36
+ "async_pipeline",
37
+ "async_queue",
38
+ "async_rate_limiter",
39
+ "async_stream_reader",
40
+ "async_subprocess",
41
+ "async_task_group",
42
+ "async_test_client",
43
+ "async_timeout",
44
+ "clean_event_loop",
45
+ "event_loop_policy",
46
+ "mock_async_process",
47
+ "mock_async_sleep",
48
+ ]