pytest-api-cov 1.1.0__tar.gz → 1.1.1__tar.gz
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.
- {pytest_api_cov-1.1.0 → pytest_api_cov-1.1.1}/PKG-INFO +10 -4
- {pytest_api_cov-1.1.0 → pytest_api_cov-1.1.1}/README.md +9 -3
- {pytest_api_cov-1.1.0 → pytest_api_cov-1.1.1}/pyproject.toml +1 -1
- {pytest_api_cov-1.1.0 → pytest_api_cov-1.1.1}/src/pytest_api_cov/report.py +39 -11
- {pytest_api_cov-1.1.0 → pytest_api_cov-1.1.1}/.gitignore +0 -0
- {pytest_api_cov-1.1.0 → pytest_api_cov-1.1.1}/LICENSE +0 -0
- {pytest_api_cov-1.1.0 → pytest_api_cov-1.1.1}/src/pytest_api_cov/__init__.py +0 -0
- {pytest_api_cov-1.1.0 → pytest_api_cov-1.1.1}/src/pytest_api_cov/cli.py +0 -0
- {pytest_api_cov-1.1.0 → pytest_api_cov-1.1.1}/src/pytest_api_cov/config.py +0 -0
- {pytest_api_cov-1.1.0 → pytest_api_cov-1.1.1}/src/pytest_api_cov/frameworks.py +0 -0
- {pytest_api_cov-1.1.0 → pytest_api_cov-1.1.1}/src/pytest_api_cov/models.py +0 -0
- {pytest_api_cov-1.1.0 → pytest_api_cov-1.1.1}/src/pytest_api_cov/plugin.py +0 -0
- {pytest_api_cov-1.1.0 → pytest_api_cov-1.1.1}/src/pytest_api_cov/pytest_flags.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: pytest-api-cov
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.1
|
4
4
|
Summary: Pytest Plugin to provide API Coverage statistics for Python Web Frameworks
|
5
5
|
Author-email: Barnaby Gill <barnabasgill@gmail.com>
|
6
6
|
License: Apache-2.0
|
@@ -259,14 +259,17 @@ show_uncovered_endpoints = true
|
|
259
259
|
show_covered_endpoints = false
|
260
260
|
show_excluded_endpoints = false
|
261
261
|
|
262
|
-
# Exclude endpoints from coverage using
|
262
|
+
# Exclude endpoints from coverage using wildcard patterns with negation support
|
263
263
|
# Use * for wildcard matching, all other characters are matched literally
|
264
|
+
# Use ! at the start to negate a pattern (include what would otherwise be excluded)
|
264
265
|
exclusion_patterns = [
|
265
266
|
"/health", # Exact match
|
266
267
|
"/metrics", # Exact match
|
267
268
|
"/docs/*", # Wildcard: matches /docs/swagger, /docs/openapi, etc.
|
268
269
|
"/admin/*", # Wildcard: matches all admin endpoints
|
269
|
-
"/
|
270
|
+
"!/admin/public", # Negation: include /admin/public even though /admin/* excludes it
|
271
|
+
"/api/v1.0/*", # Exact version match (won't match /api/v1x0/*)
|
272
|
+
"!/api/v1.0/health" # Negation: include /api/v1.0/health even though /api/v1.0/* excludes it
|
270
273
|
]
|
271
274
|
|
272
275
|
# Save detailed JSON report
|
@@ -308,9 +311,12 @@ pytest --api-cov-report --api-cov-show-uncovered-endpoints=false
|
|
308
311
|
# Save JSON report
|
309
312
|
pytest --api-cov-report --api-cov-report-path=api_coverage.json
|
310
313
|
|
311
|
-
# Exclude specific endpoints (supports wildcards)
|
314
|
+
# Exclude specific endpoints (supports wildcards and negation)
|
312
315
|
pytest --api-cov-report --api-cov-exclusion-patterns="/health" --api-cov-exclusion-patterns="/docs/*"
|
313
316
|
|
317
|
+
# Exclude with negation (exclude all admin except admin/public)
|
318
|
+
pytest --api-cov-report --api-cov-exclusion-patterns="/admin/*" --api-cov-exclusion-patterns="!/admin/public"
|
319
|
+
|
314
320
|
# Verbose logging (shows discovery process)
|
315
321
|
pytest --api-cov-report -v
|
316
322
|
|
@@ -241,14 +241,17 @@ show_uncovered_endpoints = true
|
|
241
241
|
show_covered_endpoints = false
|
242
242
|
show_excluded_endpoints = false
|
243
243
|
|
244
|
-
# Exclude endpoints from coverage using
|
244
|
+
# Exclude endpoints from coverage using wildcard patterns with negation support
|
245
245
|
# Use * for wildcard matching, all other characters are matched literally
|
246
|
+
# Use ! at the start to negate a pattern (include what would otherwise be excluded)
|
246
247
|
exclusion_patterns = [
|
247
248
|
"/health", # Exact match
|
248
249
|
"/metrics", # Exact match
|
249
250
|
"/docs/*", # Wildcard: matches /docs/swagger, /docs/openapi, etc.
|
250
251
|
"/admin/*", # Wildcard: matches all admin endpoints
|
251
|
-
"/
|
252
|
+
"!/admin/public", # Negation: include /admin/public even though /admin/* excludes it
|
253
|
+
"/api/v1.0/*", # Exact version match (won't match /api/v1x0/*)
|
254
|
+
"!/api/v1.0/health" # Negation: include /api/v1.0/health even though /api/v1.0/* excludes it
|
252
255
|
]
|
253
256
|
|
254
257
|
# Save detailed JSON report
|
@@ -290,9 +293,12 @@ pytest --api-cov-report --api-cov-show-uncovered-endpoints=false
|
|
290
293
|
# Save JSON report
|
291
294
|
pytest --api-cov-report --api-cov-report-path=api_coverage.json
|
292
295
|
|
293
|
-
# Exclude specific endpoints (supports wildcards)
|
296
|
+
# Exclude specific endpoints (supports wildcards and negation)
|
294
297
|
pytest --api-cov-report --api-cov-exclusion-patterns="/health" --api-cov-exclusion-patterns="/docs/*"
|
295
298
|
|
299
|
+
# Exclude with negation (exclude all admin except admin/public)
|
300
|
+
pytest --api-cov-report --api-cov-exclusion-patterns="/admin/*" --api-cov-exclusion-patterns="!/admin/public"
|
301
|
+
|
296
302
|
# Verbose logging (shows discovery process)
|
297
303
|
pytest --api-cov-report -v
|
298
304
|
|
@@ -30,31 +30,59 @@ def categorise_endpoints(
|
|
30
30
|
) -> Tuple[List[str], List[str], List[str]]:
|
31
31
|
"""Categorise endpoints into covered, uncovered, and excluded.
|
32
32
|
|
33
|
-
Exclusion patterns support simple wildcard matching:
|
33
|
+
Exclusion patterns support simple wildcard matching with negation:
|
34
34
|
- Use * for wildcard (matches any characters)
|
35
|
+
- Use ! at the start to negate a pattern (include what would otherwise be excluded)
|
35
36
|
- All other characters are matched literally
|
36
|
-
- Examples: "/admin/*", "/health", "/
|
37
|
+
- Examples: "/admin/*", "/health", "!users/bob" (negates exclusion)
|
38
|
+
- Pattern order matters: exclusions are applied first, then negations override them
|
37
39
|
"""
|
38
40
|
covered, uncovered, excluded = [], [], []
|
39
41
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
if not exclusion_patterns:
|
43
|
+
compiled_exclusions = None
|
44
|
+
compiled_negations = None
|
45
|
+
else:
|
46
|
+
# Separate exclusion and negation patterns
|
47
|
+
exclusion_only = [p for p in exclusion_patterns if not p.startswith("!")]
|
48
|
+
negation_only = [p[1:] for p in exclusion_patterns if p.startswith("!")] # Remove the '!' prefix
|
49
|
+
|
50
|
+
compiled_exclusions = (
|
51
|
+
[re.compile("^" + re.escape(pattern).replace(r"\*", ".*") + "$") for pattern in exclusion_only]
|
52
|
+
if exclusion_only
|
53
|
+
else None
|
54
|
+
)
|
55
|
+
compiled_negations = (
|
56
|
+
[re.compile("^" + re.escape(pattern).replace(r"\*", ".*") + "$") for pattern in negation_only]
|
57
|
+
if negation_only
|
58
|
+
else None
|
59
|
+
)
|
45
60
|
|
46
61
|
for endpoint in endpoints:
|
47
62
|
# Check exclusion patterns against both full "METHOD /path" and just "/path"
|
48
63
|
is_excluded = False
|
49
|
-
if
|
64
|
+
if compiled_exclusions:
|
50
65
|
# Extract path from "METHOD /path" format for pattern matching
|
51
66
|
if " " in endpoint:
|
52
67
|
_, path_only = endpoint.split(" ", 1)
|
53
|
-
is_excluded = any(p.match(endpoint) for p in
|
54
|
-
p.match(path_only) for p in
|
68
|
+
is_excluded = any(p.match(endpoint) for p in compiled_exclusions) or any(
|
69
|
+
p.match(path_only) for p in compiled_exclusions
|
70
|
+
)
|
71
|
+
else:
|
72
|
+
is_excluded = any(p.match(endpoint) for p in compiled_exclusions)
|
73
|
+
|
74
|
+
# Check negation patterns - these override exclusions
|
75
|
+
if is_excluded and compiled_negations:
|
76
|
+
if " " in endpoint:
|
77
|
+
_, path_only = endpoint.split(" ", 1)
|
78
|
+
is_negated = any(p.match(endpoint) for p in compiled_negations) or any(
|
79
|
+
p.match(path_only) for p in compiled_negations
|
55
80
|
)
|
56
81
|
else:
|
57
|
-
|
82
|
+
is_negated = any(p.match(endpoint) for p in compiled_negations)
|
83
|
+
|
84
|
+
if is_negated:
|
85
|
+
is_excluded = False # Negation overrides exclusion
|
58
86
|
|
59
87
|
if is_excluded:
|
60
88
|
excluded.append(endpoint)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|