Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

.PHONY: ruff mypy test clean clean-all version

PYPI_TOKEN := $(shell type .pypi_token 2>nul || echo "")
TEST_PYPI_TOKEN := $(shell type .test_pypi_token 2>nul || echo "")

version:
@uv version

Expand Down Expand Up @@ -65,15 +62,3 @@ pipeline-local: format clean test cover typeguard test-example test-example-para

pipeline: format test cover typeguard test-example test-example-parallel

publish: pipeline build
@echo "Publishing plugin..."
@uv publish --token $(PYPI_TOKEN)

publish-test:
@echo "Publishing plugin to test PyPI..."
@echo //$(TEST_PYPI_TOKEN)//
@uv publish --token $(TEST_PYPI_TOKEN) --index testpypi

verify-publish:
@echo "Verifying plugin was published to PyPI..."
@uv run --with pytest-api-cov --no-project -- python -c "import pytest_api_cov; print(f'Plugin verified successfully. Version: {pytest_api_cov.__version__}')"
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "pytest-api-cov"
version = "1.3.5"
version = "1.3.6"
description = "Pytest Plugin to provide API Coverage statistics for Python Web Frameworks"
readme = "README.md"
authors = [{ name = "Barnaby Gill", email = "barnabasgill@gmail.com" }]
Expand Down
32 changes: 15 additions & 17 deletions src/pytest_api_cov/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ def fixture_func(request: pytest.FixtureRequest) -> Any:
yield client
return

# Last resort yield None but don't skip, so tests still run
# Last resort - yield None but don't skip, so tests still run
logger.warning(
f"> create_coverage_fixture('{fixture_name}') could not provide a client; "
"tests will run without API coverage for this fixture."
Expand All @@ -219,8 +219,19 @@ class CoverageWrapper:
def __init__(self, wrapped_client: Any) -> None:
self._wrapped = wrapped_client

_TRACKED_NAMES = frozenset({"get", "post", "put", "delete", "patch", "head", "options", "request", "open"})

def _extract_path_and_method(self, name: str, args: Any, kwargs: Any) -> tuple[str, str] | None:
"""Pull path and HTTP method from the call arguments."""
# .request(method, url, ...) - method is first arg, url is second
if name == "request":
req_method = (args[0] if args else kwargs.get("method", "GET")).upper()
req_url = args[1] if len(args) > 1 else kwargs.get("url")
if isinstance(req_url, str):
return req_url.partition("?")[0], req_method
return None

# .get(url), .post(url), .open(url), etc. - url is first arg
if args:
first = args[0]
if isinstance(first, str):
Expand All @@ -245,9 +256,9 @@ def _extract_path_and_method(self, name: str, args: Any, kwargs: Any) -> tuple[s

def __getattr__(self, name: str) -> Any:
attr = getattr(self._wrapped, name)
if name in {"get", "post", "put", "delete", "patch", "head", "options"}:
if name in self._TRACKED_NAMES:

def tracked_method(*args: Any, **kwargs: Any) -> Any:
def tracked(*args: Any, **kwargs: Any) -> Any:
response = attr(*args, **kwargs)
if recorder is not None:
pm = self._extract_path_and_method(name, args, kwargs)
Expand All @@ -256,20 +267,7 @@ def tracked_method(*args: Any, **kwargs: Any) -> Any:
recorder.record_call(path, test_name, method)
return response

return tracked_method

if name == "open":

def tracked_open(*args: Any, **kwargs: Any) -> Any:
response = attr(*args, **kwargs)
if recorder is not None:
pm = self._extract_path_and_method("OPEN", args, kwargs)
if pm:
path, method = pm
recorder.record_call(path, test_name, method)
return response

return tracked_open
return tracked

return attr

Expand Down
2 changes: 1 addition & 1 deletion uv.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading