Skip to content

Commit 43a8243

Browse files
committed
1.2.0 Add additional tests for plugin file
1 parent 271572e commit 43a8243

File tree

2 files changed

+140
-1
lines changed

2 files changed

+140
-1
lines changed

tests/unit/test_config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import pytest
77
import tomli
8-
from path import Path
8+
from pathlib import Path
99
from pydantic import ValidationError
1010

1111
from pytest_api_cov.config import (

tests/unit/test_plugin.py

Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
pytest_configure,
1414
pytest_sessionfinish,
1515
pytest_sessionstart,
16+
extract_app_from_client,
17+
wrap_client_with_coverage,
18+
create_coverage_fixture,
1619
)
1720

1821

@@ -350,3 +353,139 @@ def test_pytest_testnodedown_with_existing_worker_data(self):
350353
assert "/new" in worker_data
351354
assert "existing_test" in worker_data["/existing"]
352355
assert "new_test" in worker_data["/new"]
356+
357+
358+
def test_extract_app_from_client_variants():
359+
"""Extract app from different client shapes."""
360+
app = object()
361+
362+
class A:
363+
def __init__(self):
364+
self.app = app
365+
366+
class B:
367+
def __init__(self):
368+
self.application = app
369+
370+
class Transport:
371+
def __init__(self):
372+
self.app = app
373+
374+
class C:
375+
def __init__(self):
376+
self._transport = Transport()
377+
378+
class D:
379+
def __init__(self):
380+
self._app = app
381+
382+
assert extract_app_from_client(A()) is app
383+
assert extract_app_from_client(B()) is app
384+
assert extract_app_from_client(C()) is app
385+
assert extract_app_from_client(D()) is app
386+
assert extract_app_from_client(None) is None
387+
388+
389+
def test_wrap_client_with_coverage_records_various_call_patterns():
390+
"""Tracked client records calls for string path, request-like, and kwargs."""
391+
recorder = Mock()
392+
393+
class DummyReq:
394+
def __init__(self, path, method="GET"):
395+
class URL:
396+
def __init__(self, p):
397+
self.path = p
398+
399+
self.url = URL(path)
400+
self.method = method
401+
402+
class Client:
403+
def get(self, *args, **kwargs):
404+
return "GET-OK"
405+
406+
def open(self, *args, **kwargs):
407+
return "OPEN-OK"
408+
409+
client = Client()
410+
wrapped = wrap_client_with_coverage(client, recorder, "test_fn")
411+
412+
assert wrapped.get("/foo") == "GET-OK"
413+
recorder.record_call.assert_called_with("/foo", "test_fn", "GET")
414+
415+
recorder.reset_mock()
416+
417+
req = DummyReq("/bar", method="POST")
418+
assert wrapped.get(req) == "GET-OK"
419+
recorder.record_call.assert_called_with("/bar", "test_fn", "POST")
420+
421+
recorder.reset_mock()
422+
423+
assert wrapped.open(path="/baz", method="PUT") == "OPEN-OK"
424+
recorder.record_call.assert_called_with("/baz", "test_fn", "PUT")
425+
426+
427+
def test_create_coverage_fixture_returns_existing_client_when_coverage_disabled():
428+
"""create_coverage_fixture yields existing fixture when coverage disabled."""
429+
fixture = create_coverage_fixture("my_client", existing_fixture_name="existing")
430+
431+
class SimpleSession:
432+
def __init__(self):
433+
self.config = Mock()
434+
self.config.getoption.return_value = False
435+
436+
session = SimpleSession()
437+
438+
class Req:
439+
def __init__(self):
440+
self.node = Mock()
441+
self.node.session = session
442+
443+
def getfixturevalue(self, name):
444+
if name == "existing":
445+
return "I-AM-EXISTING-CLIENT"
446+
raise pytest.FixtureLookupError(name)
447+
448+
req = Req()
449+
raw_fixture = getattr(fixture, "__wrapped__", fixture)
450+
gen = raw_fixture(req)
451+
got = next(gen)
452+
assert got == "I-AM-EXISTING-CLIENT"
453+
with pytest.raises(StopIteration):
454+
next(gen)
455+
456+
457+
@patch("pytest_api_cov.frameworks.get_framework_adapter")
458+
def test_create_coverage_fixture_falls_back_to_app_when_no_existing_and_coverage_disabled(mock_get_adapter):
459+
"""When no existing client but an app fixture exists and coverage disabled, create tracked client."""
460+
fixture = create_coverage_fixture("my_client", existing_fixture_name=None)
461+
462+
class SimpleSession:
463+
def __init__(self):
464+
self.config = Mock()
465+
self.config.getoption.return_value = False
466+
467+
session = SimpleSession()
468+
469+
class Req:
470+
def __init__(self):
471+
self.node = Mock()
472+
self.node.session = session
473+
474+
def getfixturevalue(self, name):
475+
if name == "app":
476+
return "APP-OBJ"
477+
raise pytest.FixtureLookupError(name)
478+
479+
adapter = Mock()
480+
adapter.get_tracked_client.return_value = "CLIENT-FROM-APP"
481+
mock_get_adapter.return_value = adapter
482+
483+
req = Req()
484+
# Unwrap pytest.fixture wrapper to call the inner generator directly
485+
raw_fixture = getattr(fixture, "__wrapped__", fixture)
486+
gen = raw_fixture(req)
487+
got = next(gen)
488+
assert got == "CLIENT-FROM-APP"
489+
mock_get_adapter.assert_called_once_with("APP-OBJ")
490+
with pytest.raises(StopIteration):
491+
next(gen)

0 commit comments

Comments
 (0)