From 0e0c73c4498f8f378f299cd76ff620d4d8b229a9 Mon Sep 17 00:00:00 2001 From: Artyom Kaltovich Date: Wed, 2 Oct 2019 13:42:43 +0300 Subject: [PATCH] fix issue #24: LazyFixture only resolved when used directly, but not in lists etc. --- pytest_lazyfixture.py | 31 +++++++-- tests/test_lazyfixture.py | 138 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 163 insertions(+), 6 deletions(-) diff --git a/pytest_lazyfixture.py b/pytest_lazyfixture.py index 36b5b7d..63e42e4 100644 --- a/pytest_lazyfixture.py +++ b/pytest_lazyfixture.py @@ -49,10 +49,21 @@ def pytest_fixture_setup(fixturedef, request): def pytest_runtest_call(item): + def _rec_part(val): + if is_lazy_fixture(val): + return item._request.getfixturevalue(val.name) + elif type(val) == tuple: + return tuple(item._request.getfixturevalue(v.name) if is_lazy_fixture(v) else _rec_part(v) for v in val) + elif type(val) == list: + return list(item._request.getfixturevalue(v.name) if is_lazy_fixture(v) else _rec_part(v) for v in val) + elif isinstance(val, dict): + return {key: item._request.getfixturevalue(v.name) if is_lazy_fixture(v) else _rec_part(v) + for key, v in val.items()} + return val + if hasattr(item, 'funcargs'): for arg, val in item.funcargs.items(): - if is_lazy_fixture(val): - item.funcargs[arg] = item._request.getfixturevalue(val.name) + item.funcargs[arg] = _rec_part(val) @pytest.hookimpl(hookwrapper=True) @@ -165,11 +176,19 @@ def _tree_to_list(trees, leave): return lst -def lazy_fixture(names): - if isinstance(names, string_type): +def lazy_fixture(names=None, *args, **kwargs): + if isinstance(names, string_type) and not args and not kwargs: return LazyFixture(names) - else: - return [LazyFixture(name) for name in names] + elif not kwargs: + names = [names] if isinstance(names, string_type) else names + names, is_tuple = (list(names), True) if isinstance(names, tuple) else (names, False) + names.extend(args) + if is_tuple: + return tuple(LazyFixture(name) for name in names) + else: + return [LazyFixture(name) for name in names] + elif kwargs and not (args or names): + return {key: LazyFixture(value) for key, value in kwargs.items()} def is_lazy_fixture(val): diff --git a/tests/test_lazyfixture.py b/tests/test_lazyfixture.py index 5e21fba..c06b31d 100644 --- a/tests/test_lazyfixture.py +++ b/tests/test_lazyfixture.py @@ -698,3 +698,141 @@ def test_func(some_fixture2): """) reprec = testdir.inline_run('-s') reprec.assertoutcome(passed=2) + + +def test_list_of_fixtures(testdir): + testdir.makepyfile(""" + import pytest + + @pytest.fixture(params=[ + pytest.lazy_fixture(['one', 'two']), + pytest.lazy_fixture('one', 'two'), + [1, pytest.lazy_fixture('two')], + [pytest.lazy_fixture('one'), 2], + [pytest.lazy_fixture('one'), pytest.lazy_fixture('two')] + ]) + def some(request): + return request.param + + @pytest.fixture + def one(): + return 1 + + @pytest.fixture + def two(): + return 2 + + def test_func(some): + assert some == [1, 2] + """) + reprec = testdir.inline_run('-s') + reprec.assertoutcome(passed=5) + + +def test_tuple_of_fixtures(testdir): + testdir.makepyfile(""" + import pytest + + @pytest.fixture(params=[ + pytest.lazy_fixture(('one', 'two')), + (1, pytest.lazy_fixture('two')), + (pytest.lazy_fixture('one'), 2), + (pytest.lazy_fixture('one'), pytest.lazy_fixture('two')) + ]) + def some(request): + return request.param + + @pytest.fixture + def one(): + return 1 + + @pytest.fixture + def two(): + return 2 + + def test_func(some): + assert some == (1, 2) + """) + reprec = testdir.inline_run('-s') + reprec.assertoutcome(passed=4) + + +def test_dict_of_fixtures(testdir): + testdir.makepyfile(""" + import pytest + + @pytest.fixture(params=[ + dict(one=1, two=pytest.lazy_fixture('two')), + dict(one=pytest.lazy_fixture('one'), two=2), + dict(one=pytest.lazy_fixture('one'), two=pytest.lazy_fixture('two')) + ]) + def some(request): + return request.param + + @pytest.fixture + def one(): + return 1 + + @pytest.fixture + def two(): + return 2 + + def test_func(some): + assert some == dict(one=1, two=2) + """) + reprec = testdir.inline_run('-s') + reprec.assertoutcome(passed=3) + + +def test_list_with_collections_of_fixtures(testdir): + testdir.makepyfile(""" + import pytest + + @pytest.fixture(params=[ + [[pytest.lazy_fixture('one')], [(2,)]], + [[1], [(pytest.lazy_fixture('two'),)]], + [[pytest.lazy_fixture('one')], [(pytest.lazy_fixture('two'),)]], + ]) + def some(request): + return request.param + + @pytest.fixture + def one(): + return 1 + + @pytest.fixture + def two(): + return 2 + + def test_func(some): + assert some == [[1], [(2,)]] + """) + reprec = testdir.inline_run('-s') + reprec.assertoutcome(passed=3) + + +def test_dict_with_collections_of_fixtures(testdir): + testdir.makepyfile(""" + import pytest + + @pytest.fixture(params=[ + dict(one=[pytest.lazy_fixture('one')], two=dict(two=(2,))), + dict(one=[1], two=dict(two=(pytest.lazy_fixture('two'),))), + dict(one=[pytest.lazy_fixture('one')], two=dict(two=(pytest.lazy_fixture('two'),))) + ]) + def some(request): + return request.param + + @pytest.fixture + def one(): + return 1 + + @pytest.fixture + def two(): + return 2 + + def test_func(some): + assert some == dict(one=[1], two=dict(two=(2,))) + """) + reprec = testdir.inline_run('-s') + reprec.assertoutcome(passed=3)