From a259d8131cc6f99899037afc23e129835e6d9be6 Mon Sep 17 00:00:00 2001 From: Claudio Jolowicz Date: Sat, 6 Feb 2021 21:45:56 +0100 Subject: [PATCH] Forward additional arguments to parametrized sessions (#270) * test: Add iter_sessions fixture * test: Use iter_sessions fixture in test_kwargs * test: Rename unit.test_sessions.{test_kwargs => test_name} * test: Add test for the bare session decorator * test: Add test for decorator with python parameter * test: Add test for decorator with parametrized sessions * test: Add test for wrapper with parametrized sessions * test: Add functional test for parametrized sessions * fix: Forward additional arguments to parametrized sessions * fix: Loosen types to permit parameterized session functions --- src/nox_poetry/sessions.py | 4 +- src/nox_poetry/sessions.pyi | 7 ++- tests/functional/test_functional.py | 14 +++++ tests/unit/test_sessions.py | 80 ++++++++++++++++++++++++++++- 4 files changed, 97 insertions(+), 8 deletions(-) diff --git a/src/nox_poetry/sessions.py b/src/nox_poetry/sessions.py index afa74b5c..545b6d56 100644 --- a/src/nox_poetry/sessions.py +++ b/src/nox_poetry/sessions.py @@ -34,9 +34,9 @@ def session(*args: Any, **kwargs: Any) -> Any: [function] = args @functools.wraps(function) - def wrapper(session: nox.Session) -> None: + def wrapper(session: nox.Session, *_args, **_kwargs) -> None: proxy = Session(session) - function(proxy) + function(proxy, *_args, **_kwargs) return nox.session(wrapper, **kwargs) # type: ignore[call-overload] diff --git a/src/nox_poetry/sessions.pyi b/src/nox_poetry/sessions.pyi index c05fb848..9dfabdd7 100644 --- a/src/nox_poetry/sessions.pyi +++ b/src/nox_poetry/sessions.pyi @@ -62,11 +62,10 @@ class Session: def error(self, *args: Any) -> NoReturn: ... def skip(self, *args: Any) -> NoReturn: ... -SessionFunction = Callable[[Session], None] -NoxSessionFunction = Callable[[nox.Session], None] -SessionDecorator = Callable[[SessionFunction], NoxSessionFunction] +SessionFunction = Callable[..., None] +SessionDecorator = Callable[[SessionFunction], SessionFunction] @overload -def session(__func: SessionFunction) -> NoxSessionFunction: ... +def session(__func: SessionFunction) -> SessionFunction: ... @overload def session( __func: None = ..., diff --git a/tests/functional/test_functional.py b/tests/functional/test_functional.py index b0f868db..f45063d7 100644 --- a/tests/functional/test_functional.py +++ b/tests/functional/test_functional.py @@ -361,3 +361,17 @@ def test(session: nox_poetry.Session) -> None: packages = list_packages(test) assert set(expected) == set(packages) + + +def test_session_parametrize( + project: Project, + run_nox_with_noxfile: RunNoxWithNoxfile, +) -> None: + """It forwards parameters to sessions.""" + + @nox_poetry.session + @nox.parametrize("n", [1, 2]) + def test(session: nox_poetry.Session, n: int) -> None: + """Do nothing.""" + + run_nox_with_noxfile([test], [nox, nox_poetry]) diff --git a/tests/unit/test_sessions.py b/tests/unit/test_sessions.py index 48b36d69..135a3fe9 100644 --- a/tests/unit/test_sessions.py +++ b/tests/unit/test_sessions.py @@ -1,18 +1,76 @@ """Unit tests for the sessions module.""" +from typing import Callable +from typing import Iterator + +import nox._options +import nox.manifest import nox.registry import pytest import nox_poetry -def test_kwargs() -> None: +IterSessions = Callable[[], Iterator[str]] + + +@pytest.fixture +def iter_sessions() -> IterSessions: + """List the registered nox sessions.""" + nox.registry._REGISTRY.clear() + + def _iter_sessions() -> Iterator[str]: + options = nox._options.options.namespace() + manifest = nox.manifest.Manifest(nox.registry.get(), options) + for session in manifest: + yield session.name + yield from session.signatures + + return _iter_sessions + + +def test_register(iter_sessions: IterSessions) -> None: """It registers the session function.""" + @nox_poetry.session + def tests(session: nox_poetry.Session) -> None: + pass + + assert "tests" in iter_sessions() + + +def test_name(iter_sessions: IterSessions) -> None: + """It registers the session function under the given name.""" + @nox_poetry.session(name="tests-renamed") def tests(session: nox_poetry.Session) -> None: pass - assert "tests-renamed" in nox.registry.get() + assert "tests-renamed" in iter_sessions() + + +def test_python(iter_sessions: IterSessions) -> None: + """It registers the session function for every python version.""" + + @nox_poetry.session(python=["3.8", "3.9"]) + def tests(session: nox_poetry.Session) -> None: + pass + + assert set(iter_sessions()) == {"tests", "tests-3.8", "tests-3.9"} + + +def test_parametrize(iter_sessions: IterSessions) -> None: + """It registers the session function for every parameter.""" + + @nox_poetry.session + @nox.parametrize("sphinx", ["2.4.4", "3.4.3"]) + def tests(session: nox_poetry.Session, sphinx: str) -> None: + session.install(f"sphinx=={sphinx}") + + assert set(iter_sessions()) == { + "tests", + "tests(sphinx='2.4.4')", + "tests(sphinx='3.4.3')", + } def test_wrapper(session: nox.Session) -> None: @@ -30,6 +88,24 @@ def tests(proxy: nox_poetry.Session) -> None: assert proxy._session is session +def test_wrapper_parametrize(session: nox.Session) -> None: + """It forwards parameters to the session function.""" + calls = [] + + @nox_poetry.session + @nox.parametrize("number", [1, 2]) + def tests(proxy: nox_poetry.Session, number: int) -> None: + calls.append((proxy, number)) + + tests(session, 1) # type: ignore[no-untyped-call] + tests(session, 2) # type: ignore[no-untyped-call] + + proxies, numbers = zip(*calls) + + assert all(proxy._session is session for proxy in proxies) + assert numbers == (1, 2) + + @pytest.fixture def proxy(session: nox.Session) -> nox_poetry.Session: """Fixture for session proxy."""