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.
- provide/__init__.py +3 -0
- provide/testkit/__init__.py +248 -0
- provide/testkit/archive/__init__.py +24 -0
- provide/testkit/archive/fixtures.py +217 -0
- provide/testkit/cli.py +229 -0
- provide/testkit/common/__init__.py +32 -0
- provide/testkit/common/fixtures.py +234 -0
- provide/testkit/crypto.py +163 -0
- provide/testkit/environment.py +79 -0
- provide/testkit/file/__init__.py +40 -0
- provide/testkit/file/content_fixtures.py +275 -0
- provide/testkit/file/directory_fixtures.py +105 -0
- provide/testkit/file/fixtures.py +49 -0
- provide/testkit/file/special_fixtures.py +141 -0
- provide/testkit/fixtures.py +52 -0
- provide/testkit/harness.py +122 -0
- provide/testkit/hub.py +22 -0
- provide/testkit/logger/__init__.py +39 -0
- provide/testkit/logger/hooks.py +100 -0
- provide/testkit/logger/reset.py +230 -0
- provide/testkit/main.py +22 -0
- provide/testkit/mocking/__init__.py +46 -0
- provide/testkit/mocking/fixtures.py +340 -0
- provide/testkit/process/__init__.py +48 -0
- provide/testkit/process/async_fixtures.py +410 -0
- provide/testkit/process/fixtures.py +54 -0
- provide/testkit/process/subprocess_fixtures.py +208 -0
- provide/testkit/quality/__init__.py +101 -0
- provide/testkit/quality/artifacts.py +360 -0
- provide/testkit/quality/base.py +158 -0
- provide/testkit/quality/cli.py +394 -0
- provide/testkit/quality/complexity/__init__.py +30 -0
- provide/testkit/quality/complexity/analyzer.py +392 -0
- provide/testkit/quality/complexity/fixture.py +196 -0
- provide/testkit/quality/coverage/__init__.py +36 -0
- provide/testkit/quality/coverage/fixture.py +236 -0
- provide/testkit/quality/coverage/reporter.py +150 -0
- provide/testkit/quality/coverage/tracker.py +313 -0
- provide/testkit/quality/decorators.py +380 -0
- provide/testkit/quality/documentation/__init__.py +29 -0
- provide/testkit/quality/documentation/checker.py +361 -0
- provide/testkit/quality/documentation/fixture.py +187 -0
- provide/testkit/quality/profiling/__init__.py +30 -0
- provide/testkit/quality/profiling/fixture.py +332 -0
- provide/testkit/quality/profiling/profiler.py +428 -0
- provide/testkit/quality/report.py +266 -0
- provide/testkit/quality/runner.py +319 -0
- provide/testkit/quality/security/__init__.py +29 -0
- provide/testkit/quality/security/fixture.py +196 -0
- provide/testkit/quality/security/scanner.py +338 -0
- provide/testkit/streams.py +54 -0
- provide/testkit/threading/__init__.py +38 -0
- provide/testkit/threading/basic_fixtures.py +103 -0
- provide/testkit/threading/data_fixtures.py +101 -0
- provide/testkit/threading/execution_fixtures.py +268 -0
- provide/testkit/threading/fixtures.py +50 -0
- provide/testkit/threading/sync_fixtures.py +98 -0
- provide/testkit/time/__init__.py +32 -0
- provide/testkit/time/fixtures.py +416 -0
- provide/testkit/transport/__init__.py +30 -0
- provide/testkit/transport/fixtures.py +278 -0
- provide_testkit-0.0.0.dev0.dist-info/METADATA +145 -0
- provide_testkit-0.0.0.dev0.dist-info/RECORD +66 -0
- provide_testkit-0.0.0.dev0.dist-info/WHEEL +5 -0
- provide_testkit-0.0.0.dev0.dist-info/entry_points.txt +2 -0
- provide_testkit-0.0.0.dev0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Transport and Network Testing Fixtures.
|
|
3
|
+
|
|
4
|
+
Fixtures and helpers for testing network operations, including
|
|
5
|
+
mock servers, free port allocation, and HTTP client mocking.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from collections.abc import Generator
|
|
9
|
+
from http.server import BaseHTTPRequestHandler, HTTPServer
|
|
10
|
+
import socket
|
|
11
|
+
import threading
|
|
12
|
+
from typing import Any
|
|
13
|
+
|
|
14
|
+
import pytest
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@pytest.fixture
|
|
18
|
+
def free_port() -> int:
|
|
19
|
+
"""
|
|
20
|
+
Get a free port for testing.
|
|
21
|
+
|
|
22
|
+
Returns:
|
|
23
|
+
An available port number on localhost.
|
|
24
|
+
"""
|
|
25
|
+
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
|
26
|
+
s.bind(("", 0))
|
|
27
|
+
s.listen(1)
|
|
28
|
+
port = s.getsockname()[1]
|
|
29
|
+
return port
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
@pytest.fixture
|
|
33
|
+
def mock_server(free_port) -> Generator[dict[str, Any], None, None]:
|
|
34
|
+
"""
|
|
35
|
+
Create a simple mock HTTP server for testing.
|
|
36
|
+
|
|
37
|
+
Args:
|
|
38
|
+
free_port: Free port number from fixture.
|
|
39
|
+
|
|
40
|
+
Yields:
|
|
41
|
+
Dict with server info including url, port, and server instance.
|
|
42
|
+
"""
|
|
43
|
+
responses = {}
|
|
44
|
+
requests_received = []
|
|
45
|
+
|
|
46
|
+
class MockHandler(BaseHTTPRequestHandler):
|
|
47
|
+
"""Handler for mock HTTP server."""
|
|
48
|
+
|
|
49
|
+
def do_GET(self):
|
|
50
|
+
"""Handle GET requests."""
|
|
51
|
+
requests_received.append({"method": "GET", "path": self.path, "headers": dict(self.headers)})
|
|
52
|
+
|
|
53
|
+
response = responses.get(self.path, {"status": 404, "body": b"Not Found"})
|
|
54
|
+
self.send_response(response["status"])
|
|
55
|
+
for header, value in response.get("headers", {}).items():
|
|
56
|
+
self.send_header(header, value)
|
|
57
|
+
self.end_headers()
|
|
58
|
+
self.wfile.write(response["body"])
|
|
59
|
+
|
|
60
|
+
def do_POST(self):
|
|
61
|
+
"""Handle POST requests."""
|
|
62
|
+
content_length = int(self.headers.get("Content-Length", 0))
|
|
63
|
+
body = self.rfile.read(content_length) if content_length else b""
|
|
64
|
+
|
|
65
|
+
requests_received.append(
|
|
66
|
+
{
|
|
67
|
+
"method": "POST",
|
|
68
|
+
"path": self.path,
|
|
69
|
+
"headers": dict(self.headers),
|
|
70
|
+
"body": body,
|
|
71
|
+
}
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
response = responses.get(self.path, {"status": 200, "body": b"OK"})
|
|
75
|
+
self.send_response(response["status"])
|
|
76
|
+
for header, value in response.get("headers", {}).items():
|
|
77
|
+
self.send_header(header, value)
|
|
78
|
+
self.end_headers()
|
|
79
|
+
self.wfile.write(response["body"])
|
|
80
|
+
|
|
81
|
+
def log_message(self, format, *args):
|
|
82
|
+
"""Suppress log messages."""
|
|
83
|
+
pass
|
|
84
|
+
|
|
85
|
+
server = HTTPServer(("localhost", free_port), MockHandler)
|
|
86
|
+
server_thread = threading.Thread(target=server.serve_forever)
|
|
87
|
+
server_thread.daemon = True
|
|
88
|
+
server_thread.start()
|
|
89
|
+
|
|
90
|
+
yield {
|
|
91
|
+
"url": f"http://localhost:{free_port}",
|
|
92
|
+
"port": free_port,
|
|
93
|
+
"server": server,
|
|
94
|
+
"responses": responses,
|
|
95
|
+
"requests": requests_received,
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
server.shutdown()
|
|
99
|
+
server.server_close()
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
@pytest.fixture
|
|
103
|
+
def httpx_mock_responses():
|
|
104
|
+
"""
|
|
105
|
+
Pre-configured responses for HTTPX mocking.
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
Dict of common mock responses.
|
|
109
|
+
"""
|
|
110
|
+
return {
|
|
111
|
+
"success": {
|
|
112
|
+
"status_code": 200,
|
|
113
|
+
"json": {"status": "ok", "data": {}},
|
|
114
|
+
},
|
|
115
|
+
"created": {
|
|
116
|
+
"status_code": 201,
|
|
117
|
+
"json": {"id": "123", "created": True},
|
|
118
|
+
},
|
|
119
|
+
"not_found": {
|
|
120
|
+
"status_code": 404,
|
|
121
|
+
"json": {"error": "Not found"},
|
|
122
|
+
},
|
|
123
|
+
"server_error": {
|
|
124
|
+
"status_code": 500,
|
|
125
|
+
"json": {"error": "Internal server error"},
|
|
126
|
+
},
|
|
127
|
+
"unauthorized": {
|
|
128
|
+
"status_code": 401,
|
|
129
|
+
"json": {"error": "Unauthorized"},
|
|
130
|
+
},
|
|
131
|
+
"rate_limited": {
|
|
132
|
+
"status_code": 429,
|
|
133
|
+
"headers": {"Retry-After": "60"},
|
|
134
|
+
"json": {"error": "Rate limit exceeded"},
|
|
135
|
+
},
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
@pytest.fixture
|
|
140
|
+
def mock_websocket():
|
|
141
|
+
"""
|
|
142
|
+
Mock WebSocket connection for testing.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
Mock WebSocket with send, receive, close methods.
|
|
146
|
+
"""
|
|
147
|
+
from unittest.mock import AsyncMock, Mock
|
|
148
|
+
|
|
149
|
+
ws = Mock()
|
|
150
|
+
ws.send = AsyncMock()
|
|
151
|
+
ws.receive = AsyncMock(return_value={"type": "text", "data": "message"})
|
|
152
|
+
ws.close = AsyncMock()
|
|
153
|
+
ws.accept = AsyncMock()
|
|
154
|
+
ws.ping = AsyncMock()
|
|
155
|
+
ws.pong = AsyncMock()
|
|
156
|
+
|
|
157
|
+
# State properties
|
|
158
|
+
ws.closed = False
|
|
159
|
+
ws.url = "ws://localhost:8000/ws"
|
|
160
|
+
|
|
161
|
+
return ws
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
@pytest.fixture
|
|
165
|
+
def mock_dns_resolver():
|
|
166
|
+
"""
|
|
167
|
+
Mock DNS resolver for testing.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
Mock resolver with resolve method.
|
|
171
|
+
"""
|
|
172
|
+
from unittest.mock import Mock
|
|
173
|
+
|
|
174
|
+
resolver = Mock()
|
|
175
|
+
resolver.resolve = Mock(return_value=["127.0.0.1", "::1"])
|
|
176
|
+
resolver.reverse = Mock(return_value="localhost")
|
|
177
|
+
resolver.clear_cache = Mock()
|
|
178
|
+
|
|
179
|
+
return resolver
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
@pytest.fixture
|
|
183
|
+
def tcp_client_server(free_port) -> Generator[dict[str, Any], None, None]:
|
|
184
|
+
"""
|
|
185
|
+
Create a TCP client-server pair for testing.
|
|
186
|
+
|
|
187
|
+
Yields:
|
|
188
|
+
Dict with client socket, server socket, and port info.
|
|
189
|
+
"""
|
|
190
|
+
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
191
|
+
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
192
|
+
server_socket.bind(("localhost", free_port))
|
|
193
|
+
server_socket.listen(1)
|
|
194
|
+
|
|
195
|
+
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
196
|
+
|
|
197
|
+
# Run server accept in thread
|
|
198
|
+
connection = None
|
|
199
|
+
|
|
200
|
+
def accept_connection():
|
|
201
|
+
nonlocal connection
|
|
202
|
+
connection, _ = server_socket.accept()
|
|
203
|
+
|
|
204
|
+
accept_thread = threading.Thread(target=accept_connection)
|
|
205
|
+
accept_thread.daemon = True
|
|
206
|
+
accept_thread.start()
|
|
207
|
+
|
|
208
|
+
# Connect client
|
|
209
|
+
client_socket.connect(("localhost", free_port))
|
|
210
|
+
accept_thread.join(timeout=1)
|
|
211
|
+
|
|
212
|
+
yield {
|
|
213
|
+
"client": client_socket,
|
|
214
|
+
"server": connection,
|
|
215
|
+
"server_socket": server_socket,
|
|
216
|
+
"port": free_port,
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
# Cleanup
|
|
220
|
+
client_socket.close()
|
|
221
|
+
if connection:
|
|
222
|
+
connection.close()
|
|
223
|
+
server_socket.close()
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
@pytest.fixture
|
|
227
|
+
def mock_ssl_context():
|
|
228
|
+
"""
|
|
229
|
+
Mock SSL context for testing secure connections.
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
Mock SSL context with common methods.
|
|
233
|
+
"""
|
|
234
|
+
from unittest.mock import Mock
|
|
235
|
+
|
|
236
|
+
context = Mock()
|
|
237
|
+
context.load_cert_chain = Mock()
|
|
238
|
+
context.load_verify_locations = Mock()
|
|
239
|
+
context.set_ciphers = Mock()
|
|
240
|
+
context.wrap_socket = Mock()
|
|
241
|
+
context.check_hostname = True
|
|
242
|
+
context.verify_mode = 2 # ssl.CERT_REQUIRED
|
|
243
|
+
|
|
244
|
+
return context
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
@pytest.fixture
|
|
248
|
+
def network_timeout():
|
|
249
|
+
"""
|
|
250
|
+
Provide network timeout configuration for tests.
|
|
251
|
+
|
|
252
|
+
Returns:
|
|
253
|
+
Dict with timeout values for different operations.
|
|
254
|
+
"""
|
|
255
|
+
return {
|
|
256
|
+
"connect": 5.0,
|
|
257
|
+
"read": 10.0,
|
|
258
|
+
"write": 10.0,
|
|
259
|
+
"total": 30.0,
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
@pytest.fixture
|
|
264
|
+
def mock_http_headers():
|
|
265
|
+
"""
|
|
266
|
+
Common HTTP headers for testing.
|
|
267
|
+
|
|
268
|
+
Returns:
|
|
269
|
+
Dict of typical HTTP headers.
|
|
270
|
+
"""
|
|
271
|
+
return {
|
|
272
|
+
"User-Agent": "TestClient/1.0",
|
|
273
|
+
"Accept": "application/json",
|
|
274
|
+
"Content-Type": "application/json",
|
|
275
|
+
"Authorization": "Bearer test_token",
|
|
276
|
+
"X-Request-ID": "test-request-123",
|
|
277
|
+
"X-Correlation-ID": "test-correlation-456",
|
|
278
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: provide-testkit
|
|
3
|
+
Version: 0.0.0.dev0
|
|
4
|
+
Summary: Testing utilities and fixtures for the provide ecosystem.
|
|
5
|
+
Author-email: Tim Perkins <code@tim.life>
|
|
6
|
+
Maintainer-email: "provide.io" <code@provide.io>
|
|
7
|
+
License: Apache-2.0
|
|
8
|
+
Project-URL: Homepage, https://github.com/provide-io/provide-testkit
|
|
9
|
+
Project-URL: Repository, https://github.com/provide-io/provide-testkit
|
|
10
|
+
Project-URL: Issues, https://github.com/provide-io/provide-testkit/issues
|
|
11
|
+
Keywords: testing,fixtures,mocking,pytest,provide
|
|
12
|
+
Classifier: Development Status :: 3 - Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Classifier: Topic :: Software Development :: Testing
|
|
21
|
+
Classifier: Topic :: Software Development :: Testing :: Mocking
|
|
22
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: >=3.11
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
Requires-Dist: provide-foundation>=0.1.0
|
|
27
|
+
Requires-Dist: click>=8.1.7
|
|
28
|
+
Requires-Dist: pytest>=8.3.5
|
|
29
|
+
Requires-Dist: pytest-asyncio>=0.26.0
|
|
30
|
+
Requires-Dist: pytest-cov>=6.3.0
|
|
31
|
+
Requires-Dist: pytest-mock>=3.15.0
|
|
32
|
+
Requires-Dist: pytest-xdist>=3.8.0
|
|
33
|
+
Requires-Dist: mkdocs-material>=9.6.20
|
|
34
|
+
Provides-Extra: quality
|
|
35
|
+
Requires-Dist: ruff>=0.11.8; extra == "quality"
|
|
36
|
+
Requires-Dist: mypy>=1.17.1; extra == "quality"
|
|
37
|
+
Requires-Dist: bandit>=1.8.3; extra == "quality"
|
|
38
|
+
Requires-Dist: coverage[toml]>=7.0.0; extra == "quality"
|
|
39
|
+
Requires-Dist: radon>=6.0.0; extra == "quality"
|
|
40
|
+
Requires-Dist: interrogate>=1.5.0; extra == "quality"
|
|
41
|
+
Provides-Extra: typecheck
|
|
42
|
+
Requires-Dist: mypy>=1.17.1; extra == "typecheck"
|
|
43
|
+
Requires-Dist: pyright>=1.1.401; extra == "typecheck"
|
|
44
|
+
Requires-Dist: pyre-check>=0.9.23; extra == "typecheck"
|
|
45
|
+
Requires-Dist: pyre-extensions>=0.0.32; extra == "typecheck"
|
|
46
|
+
Requires-Dist: pyrefly>=0.18.1; extra == "typecheck"
|
|
47
|
+
Requires-Dist: ty>=0.0.1a6; extra == "typecheck"
|
|
48
|
+
Requires-Dist: types-cryptography>=3.3.23.2; extra == "typecheck"
|
|
49
|
+
Requires-Dist: types-grpcio>=1.0.0.20250603; extra == "typecheck"
|
|
50
|
+
Requires-Dist: types-toml>=0.10.8.20240310; extra == "typecheck"
|
|
51
|
+
Requires-Dist: types-protobuf>=6.30.2.20250516; extra == "typecheck"
|
|
52
|
+
Requires-Dist: types-click>=7.1.8; extra == "typecheck"
|
|
53
|
+
Provides-Extra: advanced-testing
|
|
54
|
+
Requires-Dist: hypothesis>=6.131.28; extra == "advanced-testing"
|
|
55
|
+
Requires-Dist: freezegun>=1.5.1; extra == "advanced-testing"
|
|
56
|
+
Requires-Dist: behave>=1.2.6; extra == "advanced-testing"
|
|
57
|
+
Requires-Dist: pytest-benchmark>=5.1.0; extra == "advanced-testing"
|
|
58
|
+
Requires-Dist: pytest-testmon>=2.1.3; extra == "advanced-testing"
|
|
59
|
+
Provides-Extra: profiling
|
|
60
|
+
Requires-Dist: memray>=1.17.2; extra == "profiling"
|
|
61
|
+
Requires-Dist: viztracer>=1.0.2; extra == "profiling"
|
|
62
|
+
Provides-Extra: transport
|
|
63
|
+
Requires-Dist: httpx>=0.27.0; extra == "transport"
|
|
64
|
+
Requires-Dist: pytest-httpx>=0.35.0; extra == "transport"
|
|
65
|
+
Requires-Dist: h2>=4.3.0; extra == "transport"
|
|
66
|
+
Provides-Extra: crypto
|
|
67
|
+
Requires-Dist: cryptography>=45.0.7; extra == "crypto"
|
|
68
|
+
Requires-Dist: types-cryptography>=3.3.23.2; extra == "crypto"
|
|
69
|
+
Provides-Extra: process
|
|
70
|
+
Requires-Dist: psutil>=7.0.0; extra == "process"
|
|
71
|
+
Provides-Extra: grpc
|
|
72
|
+
Requires-Dist: grpc-stubs>=1.53.0.6; extra == "grpc"
|
|
73
|
+
Requires-Dist: grpcio>=1.73.0; extra == "grpc"
|
|
74
|
+
Requires-Dist: grpcio-tools>=1.73.0; extra == "grpc"
|
|
75
|
+
Requires-Dist: grpcio-health-checking>=1.73.0; extra == "grpc"
|
|
76
|
+
Provides-Extra: build
|
|
77
|
+
Requires-Dist: hatch>=1.14.1; extra == "build"
|
|
78
|
+
Requires-Dist: twine>=6.1.0; extra == "build"
|
|
79
|
+
Requires-Dist: uv>=0.6.5; extra == "build"
|
|
80
|
+
Requires-Dist: pre-commit>=3.5.0; extra == "build"
|
|
81
|
+
Provides-Extra: docs
|
|
82
|
+
Requires-Dist: mkdocs>=1.6.0; extra == "docs"
|
|
83
|
+
Requires-Dist: mkdocs-material>=9.6.0; extra == "docs"
|
|
84
|
+
Requires-Dist: mkdocstrings[python]>=0.26.0; extra == "docs"
|
|
85
|
+
Requires-Dist: mkdocs-autorefs>=1.4.0; extra == "docs"
|
|
86
|
+
Requires-Dist: mike>=2.1.0; extra == "docs"
|
|
87
|
+
Requires-Dist: mkdocs-gen-files>=0.5.0; extra == "docs"
|
|
88
|
+
Requires-Dist: mkdocs-literate-nav>=0.6.0; extra == "docs"
|
|
89
|
+
Requires-Dist: mkdocs-section-index>=0.3.0; extra == "docs"
|
|
90
|
+
Requires-Dist: markdown-callouts>=0.4; extra == "docs"
|
|
91
|
+
Requires-Dist: markdown-exec>=1.8; extra == "docs"
|
|
92
|
+
Requires-Dist: markdown-include>=0.8.0; extra == "docs"
|
|
93
|
+
Requires-Dist: pymdown-extensions>=10.16.0; extra == "docs"
|
|
94
|
+
Requires-Dist: mkdocs-git-revision-date-localized-plugin>=1.2.0; extra == "docs"
|
|
95
|
+
Requires-Dist: mkdocs-macros-plugin>=1.0.0; extra == "docs"
|
|
96
|
+
Requires-Dist: mkdocs-include-markdown-plugin>=7.0.0; extra == "docs"
|
|
97
|
+
Requires-Dist: mkdocs-coverage>=1.0; extra == "docs"
|
|
98
|
+
Requires-Dist: mkdocs-llmstxt>=0.2; extra == "docs"
|
|
99
|
+
Requires-Dist: mkdocs-minify-plugin>=0.8; extra == "docs"
|
|
100
|
+
Requires-Dist: mkdocs-redirects>=1.2; extra == "docs"
|
|
101
|
+
Requires-Dist: linkchecker; extra == "docs"
|
|
102
|
+
Requires-Dist: pygments>=2.19.0; extra == "docs"
|
|
103
|
+
Requires-Dist: griffe>=1.14.0; extra == "docs"
|
|
104
|
+
Requires-Dist: watchdog>=3.0.0; extra == "docs"
|
|
105
|
+
Requires-Dist: pyyaml>=6.0.0; extra == "docs"
|
|
106
|
+
Provides-Extra: utils
|
|
107
|
+
Requires-Dist: pyyaml>=6.0.2; extra == "utils"
|
|
108
|
+
Requires-Dist: reuse>=1.1.0; extra == "utils"
|
|
109
|
+
Requires-Dist: tabulate>=0.9.0; extra == "utils"
|
|
110
|
+
Requires-Dist: pynguin>=0.40.0; extra == "utils"
|
|
111
|
+
Requires-Dist: sapp>=0.4; extra == "utils"
|
|
112
|
+
Provides-Extra: standard
|
|
113
|
+
Requires-Dist: provide-testkit[crypto,process,quality,transport]; extra == "standard"
|
|
114
|
+
Provides-Extra: grpc-dev
|
|
115
|
+
Requires-Dist: provide-testkit[grpc,standard,typecheck]; extra == "grpc-dev"
|
|
116
|
+
Provides-Extra: pyvider-dev
|
|
117
|
+
Requires-Dist: provide-testkit[advanced-testing,build,grpc,profiling,standard,typecheck]; extra == "pyvider-dev"
|
|
118
|
+
Provides-Extra: all
|
|
119
|
+
Requires-Dist: provide-testkit[advanced-testing,build,crypto,docs,grpc,process,profiling,quality,transport,typecheck,utils]; extra == "all"
|
|
120
|
+
Provides-Extra: dev
|
|
121
|
+
Requires-Dist: provide-testkit[quality]; extra == "dev"
|
|
122
|
+
Provides-Extra: docs-standalone
|
|
123
|
+
Requires-Dist: provide-testkit[docs]; extra == "docs-standalone"
|
|
124
|
+
|
|
125
|
+
# Provide TestKit
|
|
126
|
+
|
|
127
|
+

|
|
128
|
+

|
|
129
|
+

|
|
130
|
+
|
|
131
|
+
**Comprehensive testing utilities and fixtures for the [provide ecosystem](https://github.com/provide-io)**
|
|
132
|
+
|
|
133
|
+
TestKit provides a unified testing framework designed specifically for applications built with `provide-foundation`. It offers intelligent context detection, extensive fixture libraries, and seamless integration with popular testing frameworks.
|
|
134
|
+
|
|
135
|
+
## โจ Key Features
|
|
136
|
+
|
|
137
|
+
- ๐ **Smart Context Detection** - Automatically detects testing environments
|
|
138
|
+
- ๐๏ธ **Foundation Integration** - Native support for provide-foundation components
|
|
139
|
+
- ๐งช **Comprehensive Fixtures** - Pre-built fixtures for common testing scenarios
|
|
140
|
+
- ๐ **CLI Testing Support** - Advanced utilities for testing Click-based applications
|
|
141
|
+
- ๐ **Crypto Testing** - Certificate and key generation utilities
|
|
142
|
+
- ๐ **Transport Mocking** - HTTP, WebSocket, and network testing tools
|
|
143
|
+
- ๐ **File System Utilities** - Temporary files, directories, and archive testing
|
|
144
|
+
- โก **Async Support** - Full async/await testing capabilities
|
|
145
|
+
- ๐งต **Thread Safety Testing** - Multi-threading test utilities
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
provide/__init__.py,sha256=qMJSY8G11XRdZRyLfSmdw1dfEr_T_22pusBooEpMcV4,99
|
|
2
|
+
provide/testkit/__init__.py,sha256=InhdGB6-Lc3R6fwMHBJiHjFsH_RemLxGZO6QbVZToWw,6544
|
|
3
|
+
provide/testkit/cli.py,sha256=WAU62h5xsO8R_khFvKO48kWQUQxQAV1-Ip870RZKuXE,7026
|
|
4
|
+
provide/testkit/crypto.py,sha256=K65rAK1sd7biNs3HlLdYKml799vyN3UsRps9Zahl-n0,6023
|
|
5
|
+
provide/testkit/environment.py,sha256=kDw15-zC-QDzhWj1U5aQdRlI3pX8MGhql1HdLe2umrk,2644
|
|
6
|
+
provide/testkit/fixtures.py,sha256=6NYC9_bGoETEo3q1QRg9ZnsHNfT4SAq5fk47uZCiJ5w,1585
|
|
7
|
+
provide/testkit/harness.py,sha256=_TO6IXXZMkuIxfpvnOEr2nQVkrwUWHqNVkacAErdXrk,4181
|
|
8
|
+
provide/testkit/hub.py,sha256=2ndWKV4G-5L_sKgXbhFSVQSaDmCY91N_OGYn7fAfUjI,594
|
|
9
|
+
provide/testkit/main.py,sha256=FkPlV3mTx1Zjg_9SXln_m3CxxFiax9oEmuRBOf210lQ,374
|
|
10
|
+
provide/testkit/streams.py,sha256=c8vWlVatTpOUIfsna5JBYwSWh_Z70Ne7GwQUFv1o2Aw,1288
|
|
11
|
+
provide/testkit/archive/__init__.py,sha256=5x-EB_0q2S1t6uyTzvTXdiylbGGI3iKylekPtA07ygg,609
|
|
12
|
+
provide/testkit/archive/fixtures.py,sha256=XoDUThDqPVsTl_gmdGUDp9M9MSUBUjtftO4J9Y6WDmE,7012
|
|
13
|
+
provide/testkit/common/__init__.py,sha256=lgXtN6d_e7twNNp_p83lXCRikHV0TGSKl72DkCNcFIA,717
|
|
14
|
+
provide/testkit/common/fixtures.py,sha256=aGE25_BLwrh29y9XMPI20wvm3Vi0SaTeaPtvBsqqpds,5770
|
|
15
|
+
provide/testkit/file/__init__.py,sha256=qK_HA8YTGWJPQBbO3CsGJDk830kpLzZ6kJudazUtNBg,883
|
|
16
|
+
provide/testkit/file/content_fixtures.py,sha256=L3Se7q7LVrNx4ZF9qwmV3gWt4HW8ckUXCFQPS2uI9fU,6874
|
|
17
|
+
provide/testkit/file/directory_fixtures.py,sha256=8P8EmvTdG_9W2cykNdvkqh6m5ec9If60pLdpRTBn6Zw,2576
|
|
18
|
+
provide/testkit/file/fixtures.py,sha256=nXrzQooqwyRfDWt4U2xQ6QstfIZMNPslIbP60o5-U0U,1209
|
|
19
|
+
provide/testkit/file/special_fixtures.py,sha256=IrjFTjpYFZYlXYzuHBhZ-bhimSeacoGfATL-j7kBTps,3381
|
|
20
|
+
provide/testkit/logger/__init__.py,sha256=RCKNUblvCdk-Z-rz0rAUKjkHWu8n10P0C1h-bnlHzIU,881
|
|
21
|
+
provide/testkit/logger/hooks.py,sha256=dMIloM0dsH4ulweQTDMc-okBDQsmRHuUa-IdcSdluko,2685
|
|
22
|
+
provide/testkit/logger/reset.py,sha256=127pgSLrL2LqXrIsNofo6-lE8c4kcT47mAublyf67BA,7083
|
|
23
|
+
provide/testkit/mocking/__init__.py,sha256=vDeMDrmWhygbhWj3LeYwoF1dK5DXdEhd-dQwowpMa7w,895
|
|
24
|
+
provide/testkit/mocking/fixtures.py,sha256=tFI6eWwsaKCmEnVbp6Y7_7OngvW14frfxmjVW9aOSv8,8286
|
|
25
|
+
provide/testkit/process/__init__.py,sha256=ehKgjMsmci5ksWVAd5Q9Oz60ZUU-OZmfLIE_MXLCJu8,1125
|
|
26
|
+
provide/testkit/process/async_fixtures.py,sha256=Q24LgBPkeQferHppRFTF8yOYE2xWLWtvEsQ2Qogcpa4,10214
|
|
27
|
+
provide/testkit/process/fixtures.py,sha256=XV-6l-9SKmWvv-loDU0oP_hBSeli_52to7iUDigZwVM,1299
|
|
28
|
+
provide/testkit/process/subprocess_fixtures.py,sha256=B7vb98wiwgaS_-H4oVcB0nhRsUnIwCcifW_2uLPrv8M,5832
|
|
29
|
+
provide/testkit/quality/__init__.py,sha256=L23_t5gv23CWkVBv2iZQBguI9fFZ17l2IKfZZCrDDWU,2734
|
|
30
|
+
provide/testkit/quality/artifacts.py,sha256=up-zobrdgrG8bC08KOYPVQlkt4nVK0IyA6eZWlqhSc8,12005
|
|
31
|
+
provide/testkit/quality/base.py,sha256=87UUrUANH1aLcmhyWDGdyh9rAudtt2XAGTptqRxuLOE,4610
|
|
32
|
+
provide/testkit/quality/cli.py,sha256=AuzcQtkpai3784PWEPpwqrX5AQO8TZahZWYmxJJ-vuo,13933
|
|
33
|
+
provide/testkit/quality/decorators.py,sha256=_bnM_84vDQWWOjYWouQOq4KTEeaKVD-gXu0lePwYYlQ,12215
|
|
34
|
+
provide/testkit/quality/report.py,sha256=NqeDUYUtiYt2He1SDhW7PQ7hfbeRcQHglXN1YloA0hQ,9714
|
|
35
|
+
provide/testkit/quality/runner.py,sha256=ZBnGXyL9sYOmmzED_BD76HjUZ5tU6QGC8ASeTIhtIMA,11087
|
|
36
|
+
provide/testkit/quality/complexity/__init__.py,sha256=XNAWPqMCyv8jwSjsnbSLhJ_K8P-Ybyuz48bneJ3tUW0,859
|
|
37
|
+
provide/testkit/quality/complexity/analyzer.py,sha256=TsVVsJbdozlDpb3wwxbSG0nfcqur2qQuHhg9YiLzYTw,14215
|
|
38
|
+
provide/testkit/quality/complexity/fixture.py,sha256=wFkSyW9kr8bfJykxIDcgNPg2qphXAwFJxLMhn4M5GWA,6401
|
|
39
|
+
provide/testkit/quality/coverage/__init__.py,sha256=WnBDtV8GfJsJ5wMUq5w9tUOF2kUSrf73Pejj2AhpusE,1037
|
|
40
|
+
provide/testkit/quality/coverage/fixture.py,sha256=IOVeHU2Ly3osfGIyh7wr_aC4ySktrRXaHQ5g7UvH_Yc,7096
|
|
41
|
+
provide/testkit/quality/coverage/reporter.py,sha256=7EvwJy_kJ8jKjmbQMvX2eywnqvWyIMkGTb1IuT5nLAY,4757
|
|
42
|
+
provide/testkit/quality/coverage/tracker.py,sha256=Y-JV8uAwQeEYIadlM9qAnra4EUkcJQ7nzNorrm6n-cs,10522
|
|
43
|
+
provide/testkit/quality/documentation/__init__.py,sha256=Rnk4C154479y1zROsgqAve3fgkaEwyAi0IFH6axF2rE,862
|
|
44
|
+
provide/testkit/quality/documentation/checker.py,sha256=1xmHRJjLrR_5AZQFfqUA0m7AvLd_Zm6X6lBRGQmshbc,13347
|
|
45
|
+
provide/testkit/quality/documentation/fixture.py,sha256=hj_h3sBHrLCUqUqIONpylRgYomrLhpfud9vJPBKNJ0I,5582
|
|
46
|
+
provide/testkit/quality/profiling/__init__.py,sha256=54wTQ7robTWwafcWrGf3UI-ERlEZzZZRWtnPJYS-k4s,874
|
|
47
|
+
provide/testkit/quality/profiling/fixture.py,sha256=Lq9tJA87zwiENpNsDHxsvk7qnuJ3thCtJ9sruNFiqX0,10655
|
|
48
|
+
provide/testkit/quality/profiling/profiler.py,sha256=5LXRUl1S5o7h69w8iltxIMWBigP2GcHEsSjvPgatnxk,14671
|
|
49
|
+
provide/testkit/quality/security/__init__.py,sha256=4U-VzGta5E-ojMIQImDdf9qKObCPQP-SM6EgUNFR1Gs,793
|
|
50
|
+
provide/testkit/quality/security/fixture.py,sha256=5ZDbQVgi-9a8XCmpxDD97S6uoxFSe8UzXGZ35HDu9mI,6175
|
|
51
|
+
provide/testkit/quality/security/scanner.py,sha256=GyKz-AoT4ncK6b44tN7lifBUdovbT2T5k5XS4thTp6o,11475
|
|
52
|
+
provide/testkit/threading/__init__.py,sha256=a28uyau85xVbcLhTmUu4VujV_IDHMbvZ00scrYvODrw,895
|
|
53
|
+
provide/testkit/threading/basic_fixtures.py,sha256=VwG5fXFRQAhw20SbsJWI7RXz2rgyz9pjy8IexQ4GQw0,2263
|
|
54
|
+
provide/testkit/threading/data_fixtures.py,sha256=BYU3QC6zeVFSYaLNGzP--rIe0tn4hJ9qdhj4KIUkYiM,2369
|
|
55
|
+
provide/testkit/threading/execution_fixtures.py,sha256=l8XrN2b4xIyMWKgGEPlkl1EKrha328AMmj0rKyVgF6s,8215
|
|
56
|
+
provide/testkit/threading/fixtures.py,sha256=iDzdFtPE-LAky6VSLdm9edVrqidllT8nXHYtNuEymlk,1267
|
|
57
|
+
provide/testkit/threading/sync_fixtures.py,sha256=sPeN8CSe4tzPkrbwfF2y5lcB0VqyW8EyhXt4YKWOFAU,2069
|
|
58
|
+
provide/testkit/time/__init__.py,sha256=AXBJ3GLVigLYkBdUZugna7QnROrNnlxO0tRCR5Op_CI,667
|
|
59
|
+
provide/testkit/time/fixtures.py,sha256=kEaP7CD9PXyBHtmNXELCDG06AKQhsnJIqJKEjVM-cog,11355
|
|
60
|
+
provide/testkit/transport/__init__.py,sha256=JnMNfZdBZRXsbFF2OIXhxN29jlMHF1kiiB1aPXTS_oQ,688
|
|
61
|
+
provide/testkit/transport/fixtures.py,sha256=1gHagcopJV96rnJilYb7TOe1O283u_a7E-Eh__6Etr8,7161
|
|
62
|
+
provide_testkit-0.0.0.dev0.dist-info/METADATA,sha256=2Jmk17Ar1x3qA7M-xSbojLHH1t6aSUkqRXQXpT2x21I,7389
|
|
63
|
+
provide_testkit-0.0.0.dev0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
64
|
+
provide_testkit-0.0.0.dev0.dist-info/entry_points.txt,sha256=i32Vb-BvoC7ThhB7jG9W3Z32bO4XGp62ZrSsj4fDKgs,62
|
|
65
|
+
provide_testkit-0.0.0.dev0.dist-info/top_level.txt,sha256=zwyv2grD4005JoQoP1v9wIYXfqgW9sgFuikW7uYZllw,8
|
|
66
|
+
provide_testkit-0.0.0.dev0.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
provide
|