summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJakub Roztocil <jakub@roztocil.co>2024-03-04 16:27:52 +0100
committerJakub Roztocil <jakub@roztocil.co>2024-03-04 16:28:03 +0100
commit3524ccf0baa9f2b3029368ab07ba5f64e62dcb1f (patch)
tree55809361933126d823d65b1ff791cad1eda13d32
parent8ac44b57ce0d4e8b8da574eb4391262c9c55b4e6 (diff)
Drop dependency on the abandoned python-lazy-fixture
-rw-r--r--setup.py1
-rw-r--r--tests/conftest.py8
-rw-r--r--tests/fixtures/pytest_lazy_fixture.py99
3 files changed, 104 insertions, 4 deletions
diff --git a/setup.py b/setup.py
index 7ebaaf58..21bdaf16 100644
--- a/setup.py
+++ b/setup.py
@@ -11,7 +11,6 @@ import httpie
tests_require = [
'pytest',
'pytest-httpbin>=0.0.6',
- 'pytest-lazy-fixture>=0.0.6',
'responses',
'pytest-mock',
'werkzeug<2.1.0'
diff --git a/tests/conftest.py b/tests/conftest.py
index 7ca172a8..9430a32e 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -3,14 +3,14 @@ import socket
import pytest
from pytest_httpbin import certs
-from .utils import ( # noqa
+from .utils import ( # noqa
HTTPBIN_WITH_CHUNKED_SUPPORT_DOMAIN,
HTTPBIN_WITH_CHUNKED_SUPPORT,
REMOTE_HTTPBIN_DOMAIN,
IS_PYOPENSSL,
mock_env
)
-from .utils.plugins_cli import ( # noqa
+from .utils.plugins_cli import ( # noqa
broken_plugin,
dummy_plugin,
dummy_plugins,
@@ -18,7 +18,9 @@ from .utils.plugins_cli import ( # noqa
httpie_plugins_success,
interface,
)
-from .utils.http_server import http_server, localhost_http_server # noqa
+from .utils.http_server import http_server, localhost_http_server # noqa
+# noinspection PyUnresolvedReferences
+from .fixtures import pytest_lazy_fixture
@pytest.fixture(scope='function', autouse=True)
diff --git a/tests/fixtures/pytest_lazy_fixture.py b/tests/fixtures/pytest_lazy_fixture.py
new file mode 100644
index 00000000..5b70d8ec
--- /dev/null
+++ b/tests/fixtures/pytest_lazy_fixture.py
@@ -0,0 +1,99 @@
+"""
+Replacement for the abandoned `pytest.lazy_fixture` <https://github.com/TvoroG/pytest-lazy-fixture>
+
+Based on <https://github.com/TvoroG/pytest-lazy-fixture/issues/65#issuecomment-1914581161>
+
+"""
+import dataclasses
+import typing
+
+import pytest
+
+
+@dataclasses.dataclass
+class LazyFixture:
+ """Lazy fixture dataclass."""
+
+ name: str
+
+
+def lazy_fixture(name: str) -> LazyFixture:
+ """Mark a fixture as lazy."""
+ return LazyFixture(name)
+
+
+# NOTE: Mimic the original API
+pytest.lazy_fixture = lazy_fixture
+
+
+def is_lazy_fixture(value: object) -> bool:
+ """Check whether a value is a lazy fixture."""
+ return isinstance(value, LazyFixture)
+
+
+def pytest_make_parametrize_id(
+ config: pytest.Config,
+ val: object,
+ argname: str,
+) -> str | None:
+ """Inject lazy fixture parametrized id.
+
+ Reference:
+ - https://bit.ly/48Off6r
+
+ Args:
+ config (pytest.Config): pytest configuration.
+ value (object): fixture value.
+ argname (str): automatic parameter name.
+
+ Returns:
+ str: new parameter id.
+ """
+ if is_lazy_fixture(val):
+ return typing.cast(LazyFixture, val).name
+ return None
+
+
+@pytest.hookimpl(tryfirst=True)
+def pytest_fixture_setup(
+ fixturedef: pytest.FixtureDef,
+ request: pytest.FixtureRequest,
+) -> object | None:
+ """Lazy fixture setup hook.
+
+ This hook will never take over a fixture setup but just simply will
+ try to resolve recursively any lazy fixture found in request.param.
+
+ Reference:
+ - https://bit.ly/3SyvsXJ
+
+ Args:
+ fixturedef (pytest.FixtureDef): fixture definition object.
+ request (pytest.FixtureRequest): fixture request object.
+
+ Returns:
+ object | None: fixture value or None otherwise.
+ """
+ if hasattr(request, "param") and request.param:
+ request.param = _resolve_lazy_fixture(request.param, request)
+ return None
+
+
+def _resolve_lazy_fixture(__val: object, request: pytest.FixtureRequest) -> object:
+ """Lazy fixture resolver.
+
+ Args:
+ __val (object): fixture value object.
+ request (pytest.FixtureRequest): pytest fixture request object.
+
+ Returns:
+ object: resolved fixture value.
+ """
+ if isinstance(__val, list | tuple):
+ return tuple(_resolve_lazy_fixture(v, request) for v in __val)
+ if isinstance(__val, typing.Mapping):
+ return {k: _resolve_lazy_fixture(v, request) for k, v in __val.items()}
+ if not is_lazy_fixture(__val):
+ return __val
+ lazy_obj = typing.cast(LazyFixture, __val)
+ return request.getfixturevalue(lazy_obj.name)