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,52 @@
1
+ """
2
+ Common Test Fixtures for Foundation.
3
+
4
+ Provides pytest fixtures for capturing output, setting up telemetry,
5
+ and other common testing scenarios across the Foundation test suite.
6
+ """
7
+
8
+ from collections.abc import Callable, Generator
9
+ import io
10
+ from typing import TextIO
11
+
12
+ import pytest
13
+
14
+ from provide.foundation import TelemetryConfig, get_hub
15
+ from provide.testkit.streams import set_log_stream_for_testing
16
+
17
+
18
+ @pytest.fixture
19
+ def captured_stderr_for_foundation() -> Generator[TextIO]:
20
+ """
21
+ Fixture to capture stderr output from Foundation's logging system.
22
+
23
+ It redirects Foundation's log stream to an `io.StringIO` buffer, yields the buffer
24
+ to the test, and then restores the original stream.
25
+ """
26
+ current_test_stream = io.StringIO()
27
+ set_log_stream_for_testing(current_test_stream)
28
+ yield current_test_stream
29
+ set_log_stream_for_testing(None)
30
+ current_test_stream.close()
31
+
32
+
33
+ @pytest.fixture
34
+ def setup_foundation_telemetry_for_test(
35
+ captured_stderr_for_foundation: TextIO,
36
+ ) -> Callable[[TelemetryConfig | None], None]:
37
+ """
38
+ Fixture providing a function to set up Foundation Telemetry for tests.
39
+
40
+ This fixture captures stderr via `captured_stderr_for_foundation`
41
+ and provides a callable to configure telemetry with custom settings.
42
+ """
43
+
44
+ def _setup(config: TelemetryConfig | None = None) -> None:
45
+ if config is None:
46
+ config = TelemetryConfig()
47
+
48
+ # Use Hub API directly instead of deprecated setup_telemetry
49
+ hub = get_hub()
50
+ hub.initialize_foundation(config, force=True)
51
+
52
+ return _setup
@@ -0,0 +1,122 @@
1
+ """
2
+ Harness Testing Utilities.
3
+
4
+ Provides utilities for testing CLI harnesses with artifact management.
5
+ """
6
+
7
+ from pathlib import Path
8
+
9
+ from provide.foundation.process.runner import run_command
10
+
11
+
12
+ class HarnessRunner:
13
+ """Test harness runner with artifact management."""
14
+
15
+ def __init__(self, artifact_root: Path):
16
+ """Initialize with artifact root directory."""
17
+ self.artifact_root = artifact_root
18
+
19
+ def run(
20
+ self,
21
+ command: list[str],
22
+ artifact_path: Path | str,
23
+ stdin: str | bytes | None = None,
24
+ timeout: float = 30.0,
25
+ cwd: Path | None = None,
26
+ ) -> tuple[int, str, str]:
27
+ """
28
+ Run command and return text output.
29
+
30
+ For binary output commands, use run_binary() instead.
31
+ """
32
+ exit_code, stdout_str, stderr_str, _, _ = self._run_internal(
33
+ command, artifact_path, stdin, timeout, cwd
34
+ )
35
+ return exit_code, stdout_str, stderr_str
36
+
37
+ def run_binary(
38
+ self,
39
+ command: list[str],
40
+ artifact_path: Path | str,
41
+ stdin: str | bytes | None = None,
42
+ timeout: float = 30.0,
43
+ cwd: Path | None = None,
44
+ ) -> tuple[int, bytes, bytes]:
45
+ """
46
+ Run command and return binary output.
47
+
48
+ Use this for commands that output binary data.
49
+ """
50
+ exit_code, _, _, stdout_bytes, stderr_bytes = self._run_internal(
51
+ command, artifact_path, stdin, timeout, cwd
52
+ )
53
+ return exit_code, stdout_bytes, stderr_bytes
54
+
55
+ def _run_internal(
56
+ self,
57
+ command: list[str],
58
+ artifact_path: Path | str,
59
+ stdin: str | bytes | None = None,
60
+ timeout: float = 30.0,
61
+ cwd: Path | None = None,
62
+ ) -> tuple[int, str, str, bytes, bytes]:
63
+ """
64
+ Internal run method that returns both text and binary outputs.
65
+
66
+ Returns:
67
+ Tuple of (exit_code, stdout_str, stderr_str, stdout_bytes, stderr_bytes)
68
+ """
69
+ # Create artifact directory
70
+ artifact_dir = self.artifact_root / artifact_path
71
+ artifact_dir.mkdir(parents=True, exist_ok=True)
72
+
73
+ # Save command and stdin
74
+ (artifact_dir / "cmd.txt").write_text(" ".join(command))
75
+ if stdin:
76
+ (artifact_dir / "stdin.txt").write_bytes(stdin.encode() if isinstance(stdin, str) else stdin)
77
+
78
+ # Run command in binary mode to handle binary outputs
79
+ result = run_command(
80
+ command,
81
+ cwd=cwd,
82
+ input=stdin,
83
+ timeout=timeout,
84
+ check=False, # Don't raise on non-zero exit
85
+ text=False, # Binary mode to handle binary data
86
+ env={"PROVIDE_TELEMETRY_DISABLED": "true"},
87
+ )
88
+
89
+ # Handle binary outputs - return as bytes for binary data, decode for text
90
+ stdout_bytes = result.stdout if isinstance(result.stdout, bytes) else result.stdout.encode()
91
+ stderr_bytes = result.stderr if isinstance(result.stderr, bytes) else result.stderr.encode()
92
+
93
+ # Try to decode as text for logging/artifacts, but preserve original bytes
94
+ try:
95
+ stdout_str = stdout_bytes.decode("utf-8")
96
+ except UnicodeDecodeError:
97
+ # For binary output, save as hex dump for debugging
98
+ import base64
99
+
100
+ stdout_str = f"[Binary data - base64]: {base64.b64encode(stdout_bytes).decode('ascii')}"
101
+
102
+ try:
103
+ stderr_str = stderr_bytes.decode("utf-8")
104
+ except UnicodeDecodeError:
105
+ stderr_str = f"[Binary stderr]: {stderr_bytes.decode('utf-8', errors='replace')}"
106
+
107
+ # Save outputs
108
+ (artifact_dir / "stdout.txt").write_text(stdout_str)
109
+ (artifact_dir / "stderr.txt").write_text(stderr_str)
110
+ (artifact_dir / "exitcode.txt").write_text(str(result.returncode))
111
+
112
+ # Save raw binary outputs for binary commands
113
+ if stdout_bytes:
114
+ (artifact_dir / "stdout.bin").write_bytes(stdout_bytes)
115
+ if stderr_bytes:
116
+ (artifact_dir / "stderr.bin").write_bytes(stderr_bytes)
117
+
118
+ # Return all formats
119
+ return result.returncode, stdout_str, stderr_str, stdout_bytes, stderr_bytes
120
+
121
+
122
+ __all__ = ["HarnessRunner"]
provide/testkit/hub.py ADDED
@@ -0,0 +1,22 @@
1
+ """
2
+ Hub Testing Fixtures for Foundation.
3
+
4
+ Provides pytest fixtures for testing hub and component functionality,
5
+ including container directories and component registration scenarios.
6
+ """
7
+
8
+ import pytest
9
+
10
+ from provide.foundation.file import temp_dir as foundation_temp_dir
11
+
12
+
13
+ @pytest.fixture(scope="session")
14
+ def default_container_directory():
15
+ """
16
+ Provides a default directory for container operations in tests.
17
+
18
+ This fixture is used by tests that need a temporary directory
19
+ for container-related operations.
20
+ """
21
+ with foundation_temp_dir() as tmp_dir:
22
+ yield tmp_dir
@@ -0,0 +1,39 @@
1
+ #
2
+ # __init__.py
3
+ #
4
+ """
5
+ Logger Testing Utilities.
6
+
7
+ Provides utilities for logger testing, including state reset,
8
+ mock fixtures, and pytest hooks for managing noisy loggers.
9
+ """
10
+
11
+ # Import reset utilities
12
+ # Import hook utilities
13
+ from provide.testkit.logger.hooks import (
14
+ DEFAULT_NOISY_LOGGERS,
15
+ get_log_level_for_noisy_loggers,
16
+ get_noisy_loggers,
17
+ pytest_runtest_setup,
18
+ suppress_loggers,
19
+ )
20
+ from provide.testkit.logger.reset import (
21
+ mock_logger,
22
+ mock_logger_factory,
23
+ reset_foundation_setup_for_testing,
24
+ reset_foundation_state,
25
+ )
26
+
27
+ __all__ = [
28
+ # Reset utilities
29
+ "mock_logger",
30
+ "mock_logger_factory",
31
+ "reset_foundation_setup_for_testing",
32
+ "reset_foundation_state",
33
+ # Hook utilities
34
+ "DEFAULT_NOISY_LOGGERS",
35
+ "get_log_level_for_noisy_loggers",
36
+ "get_noisy_loggers",
37
+ "pytest_runtest_setup",
38
+ "suppress_loggers",
39
+ ]
@@ -0,0 +1,100 @@
1
+ #
2
+ # hooks.py
3
+ #
4
+ """
5
+ Pytest Hooks for Logger Management.
6
+
7
+ Provides pytest hooks for suppressing noisy loggers during test runs.
8
+ This helps reduce test output noise from third-party libraries.
9
+ """
10
+
11
+ import logging
12
+ import os
13
+
14
+ import pytest
15
+
16
+ # Default list of commonly noisy loggers to suppress during tests
17
+ DEFAULT_NOISY_LOGGERS = [
18
+ "markdown_it",
19
+ "asyncio",
20
+ "urllib3.connectionpool",
21
+ "requests.packages.urllib3.connectionpool",
22
+ "botocore",
23
+ "boto3.resources",
24
+ "websockets.protocol",
25
+ "websockets.server",
26
+ "websockets.client",
27
+ "httpx",
28
+ "httpcore",
29
+ ]
30
+
31
+
32
+ def get_noisy_loggers() -> list[str]:
33
+ """
34
+ Get the list of loggers to suppress during tests.
35
+
36
+ Can be customized via the TESTKIT_NOISY_LOGGERS environment variable,
37
+ which should be a comma-separated list of logger names.
38
+
39
+ Returns:
40
+ List of logger names to suppress.
41
+ """
42
+ env_loggers = os.getenv("TESTKIT_NOISY_LOGGERS")
43
+ if env_loggers:
44
+ return [name.strip() for name in env_loggers.split(",") if name.strip()]
45
+ return DEFAULT_NOISY_LOGGERS
46
+
47
+
48
+ def get_log_level_for_noisy_loggers() -> int:
49
+ """
50
+ Get the log level to set for noisy loggers.
51
+
52
+ Can be customized via the TESTKIT_NOISY_LOG_LEVEL environment variable.
53
+ Defaults to WARNING level.
54
+
55
+ Returns:
56
+ Logging level (int) to set for noisy loggers.
57
+ """
58
+ level_name = os.getenv("TESTKIT_NOISY_LOG_LEVEL", "WARNING")
59
+ return getattr(logging, level_name.upper(), logging.WARNING)
60
+
61
+
62
+ @pytest.hookimpl(tryfirst=True)
63
+ def pytest_runtest_setup():
64
+ """
65
+ Hook that runs before each test setup.
66
+
67
+ This forcefully sets the log level for noisy libraries to WARNING (or custom level),
68
+ overriding any configuration that may have happened at import time
69
+ (e.g., by Textual or the application itself).
70
+ """
71
+ noisy_loggers = get_noisy_loggers()
72
+ log_level = get_log_level_for_noisy_loggers()
73
+
74
+ for logger_name in noisy_loggers:
75
+ logger = logging.getLogger(logger_name)
76
+ logger.setLevel(log_level)
77
+
78
+
79
+ def suppress_loggers(logger_names: list[str], level: int = logging.WARNING) -> None:
80
+ """
81
+ Utility function to suppress specific loggers to a given level.
82
+
83
+ Can be used directly in tests or conftest.py files for custom suppression.
84
+
85
+ Args:
86
+ logger_names: List of logger names to suppress
87
+ level: Log level to set (defaults to WARNING)
88
+ """
89
+ for logger_name in logger_names:
90
+ logger = logging.getLogger(logger_name)
91
+ logger.setLevel(level)
92
+
93
+
94
+ __all__ = [
95
+ "DEFAULT_NOISY_LOGGERS",
96
+ "get_log_level_for_noisy_loggers",
97
+ "get_noisy_loggers",
98
+ "pytest_runtest_setup",
99
+ "suppress_loggers",
100
+ ]
@@ -0,0 +1,230 @@
1
+ #
2
+ # reset.py
3
+ #
4
+ """
5
+ Logger Testing Utilities for Foundation.
6
+
7
+ Provides utilities for resetting logger state, managing configurations,
8
+ and ensuring test isolation for the Foundation logging system.
9
+ """
10
+
11
+ from unittest.mock import Mock
12
+
13
+ import pytest
14
+
15
+ # Note: Removed module-level imports to avoid circular imports
16
+ # All Foundation imports will be done within functions when needed
17
+
18
+
19
+ @pytest.fixture
20
+ def mock_logger():
21
+ """
22
+ Comprehensive mock logger for testing.
23
+
24
+ Provides compatibility with both stdlib logging and structlog interfaces,
25
+ including method call tracking and common logger attributes.
26
+
27
+ Returns:
28
+ Mock logger with debug, info, warning, error methods and structlog compatibility.
29
+ """
30
+ logger = Mock()
31
+ logger.debug = Mock()
32
+ logger.info = Mock()
33
+ logger.warning = Mock()
34
+ logger.warn = Mock() # Alias for warning
35
+ logger.error = Mock()
36
+ logger.exception = Mock()
37
+ logger.critical = Mock()
38
+ logger.fatal = Mock() # Alias for critical
39
+
40
+ # Add common logger attributes
41
+ logger.name = "mock_logger"
42
+ logger.level = 10 # DEBUG level
43
+ logger.handlers = []
44
+ logger.disabled = False
45
+
46
+ # Add structlog compatibility methods
47
+ logger.bind = Mock(return_value=logger)
48
+ logger.unbind = Mock(return_value=logger)
49
+ logger.new = Mock(return_value=logger)
50
+ logger.msg = Mock() # Alternative to info
51
+
52
+ # Add trace method for Foundation's extended logging
53
+ logger.trace = Mock()
54
+
55
+ return logger
56
+
57
+
58
+ def mock_logger_factory():
59
+ """
60
+ Factory function to create mock loggers outside of pytest context.
61
+
62
+ Useful for unit tests that need a mock logger but aren't using pytest fixtures.
63
+
64
+ Returns:
65
+ Mock logger with the same interface as the pytest fixture.
66
+ """
67
+ logger = Mock()
68
+ logger.debug = Mock()
69
+ logger.info = Mock()
70
+ logger.warning = Mock()
71
+ logger.warn = Mock()
72
+ logger.error = Mock()
73
+ logger.exception = Mock()
74
+ logger.critical = Mock()
75
+ logger.fatal = Mock()
76
+
77
+ logger.name = "mock_logger"
78
+ logger.level = 10
79
+ logger.handlers = []
80
+ logger.disabled = False
81
+
82
+ logger.bind = Mock(return_value=logger)
83
+ logger.unbind = Mock(return_value=logger)
84
+ logger.new = Mock(return_value=logger)
85
+ logger.msg = Mock()
86
+ logger.trace = Mock()
87
+
88
+ return logger
89
+
90
+
91
+ def _reset_opentelemetry_providers() -> None:
92
+ """
93
+ Reset OpenTelemetry providers to uninitialized state.
94
+
95
+ This prevents "Overriding of current TracerProvider/MeterProvider" warnings
96
+ and stream closure issues by properly resetting the global providers.
97
+ """
98
+ try:
99
+ # Reset tracing provider more thoroughly
100
+ import opentelemetry.trace as otel_trace
101
+
102
+ # Reset the Once flag to allow re-initialization
103
+ if hasattr(otel_trace, "_TRACER_PROVIDER_SET_ONCE"):
104
+ once_obj = otel_trace._TRACER_PROVIDER_SET_ONCE
105
+ if hasattr(once_obj, "_done"):
106
+ once_obj._done = False
107
+ if hasattr(once_obj, "_lock"):
108
+ with once_obj._lock:
109
+ once_obj._done = False
110
+
111
+ # Reset to NoOpTracerProvider
112
+ from opentelemetry.trace import NoOpTracerProvider
113
+
114
+ otel_trace.set_tracer_provider(NoOpTracerProvider())
115
+
116
+ except ImportError:
117
+ # OpenTelemetry tracing not available
118
+ pass
119
+ except Exception:
120
+ # Ignore errors during reset - better to continue than fail
121
+ pass
122
+
123
+ try:
124
+ # Reset metrics provider more thoroughly
125
+ import opentelemetry.metrics as otel_metrics
126
+ import opentelemetry.metrics._internal as otel_metrics_internal
127
+
128
+ # Reset the Once flag to allow re-initialization
129
+ if hasattr(otel_metrics_internal, "_METER_PROVIDER_SET_ONCE"):
130
+ once_obj = otel_metrics_internal._METER_PROVIDER_SET_ONCE
131
+ if hasattr(once_obj, "_done"):
132
+ once_obj._done = False
133
+ if hasattr(once_obj, "_lock"):
134
+ with once_obj._lock:
135
+ once_obj._done = False
136
+
137
+ # Reset to NoOpMeterProvider
138
+ from opentelemetry.metrics import NoOpMeterProvider
139
+
140
+ otel_metrics.set_meter_provider(NoOpMeterProvider())
141
+
142
+ except ImportError:
143
+ # OpenTelemetry metrics not available
144
+ pass
145
+ except Exception:
146
+ # Ignore errors during reset - better to continue than fail
147
+ pass
148
+
149
+
150
+ def reset_foundation_state() -> None:
151
+ """
152
+ Internal function to reset structlog and Foundation's state using Hub-based approach.
153
+
154
+ This resets:
155
+ - structlog configuration to defaults
156
+ - Foundation Hub state (which manages all Foundation components)
157
+ - Stream state back to defaults
158
+ - Lazy setup state tracking (if available)
159
+ - OpenTelemetry provider state (if available)
160
+ """
161
+ # Use the new internal reset APIs from Foundation's testmode module
162
+ from provide.foundation.testmode.internal import (
163
+ reset_coordinator_state,
164
+ reset_eventsets_state,
165
+ reset_hub_state,
166
+ reset_logger_state,
167
+ reset_streams_state,
168
+ reset_structlog_state,
169
+ )
170
+
171
+ # Reset in the proper order to avoid triggering reinitialization
172
+ reset_structlog_state()
173
+ reset_streams_state()
174
+
175
+ # Reset OpenTelemetry providers to avoid "Overriding" warnings and stream closure
176
+ # Note: OpenTelemetry providers are designed to prevent override for safety.
177
+ # In test environments, we suppress this reset to avoid hanging/blocking.
178
+ # The warnings are harmless in test context.
179
+ _reset_opentelemetry_providers()
180
+
181
+ # Reset lazy setup state FIRST to prevent hub operations from triggering setup
182
+ reset_logger_state()
183
+
184
+ # Clear Hub (this handles all Foundation state including logger instances)
185
+ reset_hub_state()
186
+
187
+ # Reset coordinator and event set state
188
+ reset_coordinator_state()
189
+ reset_eventsets_state()
190
+
191
+ # Final reset of logger state (after all operations that might trigger setup)
192
+ reset_logger_state()
193
+
194
+
195
+ def reset_foundation_setup_for_testing() -> None:
196
+ """
197
+ Public test utility to reset Foundation's internal state using Hub-based approach.
198
+
199
+ This function ensures clean test isolation by resetting all
200
+ Foundation state between test runs. Now uses Hub.clear_hub() which
201
+ properly resets all Foundation components.
202
+ """
203
+ # Full reset with Hub-based state management
204
+ reset_foundation_state()
205
+
206
+ # Re-register HTTP transport for tests that need it
207
+ try:
208
+ from provide.foundation.transport.http import _register_http_transport
209
+
210
+ _register_http_transport()
211
+ except ImportError:
212
+ # Transport module not available
213
+ pass
214
+
215
+ # Final reset of lazy setup state (after transport registration)
216
+ try:
217
+ from provide.foundation.logger.core import _LAZY_SETUP_STATE
218
+
219
+ _LAZY_SETUP_STATE.update({"done": False, "error": None, "in_progress": False})
220
+ except ImportError:
221
+ # Legacy state not available, skip
222
+ pass
223
+
224
+
225
+ __all__ = [
226
+ "mock_logger",
227
+ "mock_logger_factory",
228
+ "reset_foundation_setup_for_testing",
229
+ "reset_foundation_state",
230
+ ]
@@ -0,0 +1,22 @@
1
+ """Main CLI entry point for provide-testkit."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import click
6
+
7
+ from .quality.cli import quality_cli
8
+
9
+
10
+ @click.group()
11
+ @click.version_option()
12
+ def main() -> None:
13
+ """Provide Testkit - Testing utilities for the provide ecosystem."""
14
+ pass
15
+
16
+
17
+ # Add quality commands
18
+ main.add_command(quality_cli)
19
+
20
+
21
+ if __name__ == "__main__":
22
+ main()
@@ -0,0 +1,46 @@
1
+ """
2
+ Mocking utilities for the provide-io ecosystem.
3
+
4
+ Standardized mocking patterns, fixtures, and utilities to reduce
5
+ boilerplate and ensure consistent mocking across all tests.
6
+ """
7
+
8
+ from provide.testkit.mocking.fixtures import (
9
+ ANY,
10
+ AsyncMock,
11
+ MagicMock,
12
+ Mock,
13
+ PropertyMock,
14
+ assert_mock_calls,
15
+ async_mock_factory,
16
+ auto_patch,
17
+ call,
18
+ magic_mock_factory,
19
+ mock_factory,
20
+ mock_open_fixture,
21
+ patch,
22
+ patch_fixture,
23
+ patch_multiple_fixture,
24
+ property_mock_factory,
25
+ spy_fixture,
26
+ )
27
+
28
+ __all__ = [
29
+ "ANY",
30
+ "AsyncMock",
31
+ "MagicMock",
32
+ "Mock",
33
+ "PropertyMock",
34
+ "assert_mock_calls",
35
+ "async_mock_factory",
36
+ "auto_patch",
37
+ "call",
38
+ "magic_mock_factory",
39
+ "mock_factory",
40
+ "mock_open_fixture",
41
+ "patch",
42
+ "patch_fixture",
43
+ "patch_multiple_fixture",
44
+ "property_mock_factory",
45
+ "spy_fixture",
46
+ ]