From a59d602bcef5572ccb74c3bd9c85d897e05f674d Mon Sep 17 00:00:00 2001 From: holger krekel Date: Thu, 11 Jun 2009 19:49:25 +0200 Subject: [PATCH] * remove redundant call_next_provider method, thus generalizing Request object * refine according documentation --HG-- branch : trunk --- doc/test/funcargs.txt | 34 ++++++++++---------------------- py/test/funcargs.py | 30 +++++++++------------------- py/test/plugin/conftest.py | 2 +- py/test/plugin/pytest_restdoc.py | 2 +- py/test/testing/test_funcargs.py | 15 +++++++++----- py/test/testing/test_pickling.py | 2 +- 6 files changed, 32 insertions(+), 53 deletions(-) diff --git a/doc/test/funcargs.txt b/doc/test/funcargs.txt index f3dd40fc5..949375afa 100644 --- a/doc/test/funcargs.txt +++ b/doc/test/funcargs.txt @@ -174,8 +174,10 @@ object that is to be closed when the test function finishes. requesting values of other funcargs --------------------------------------------- -While setting up one function argument you may -want to retrieve another function argument. +Inside a funcarg provider, you sometimes may want to use a +different function argument which may be specified with +the test function or not. For such purposes you can +dynamically request a funcarg value: .. sourcecode:: python @@ -184,26 +186,10 @@ want to retrieve another function argument. Each function argument is only requested once per function setup. """ -Note that it does not matter if the test function -specifies the requested function argument. - -decorating other funcarg providers -++++++++++++++++++++++++++++++++++++++++ - -If you want to **decorate a function argument** that is -provided elsewhere you can ask the request object -to provide the "next" value: - -.. sourcecode:: python - - def pytest_funcarg__myfile(self, request): - myfile = request.call_next_provider() - # do something extra - return myfile - -This will raise a ``request.Error`` exception if there -is no next provider left. See the `decorator example`_ -for a use of this method. +You can also use this function if you want to `decorate a funcarg`_ +locally, i.e. you want to provide the normal value but add/do something +extra. If a provider cannot be found a ``request.Error`` exception will be +raised. .. _`test generators`: @@ -516,7 +502,7 @@ to your AcceptFuncarg and drive running of tools or applications and provide ways to do assertions about the output. -.. _`decorator example`: +.. _`decorate a funcarg`: example: decorating a funcarg in a test module -------------------------------------------------------------- @@ -528,7 +514,7 @@ extend the `accept example`_ by putting this in our test class: .. sourcecode:: python def pytest_funcarg__accept(self, request): - arg = request.call_next_provider() + arg = request.getfuncargvalue("accept") # call the next provider # create a special layout in our tempdir arg.tmpdir.mkdir("special") return arg diff --git a/py/test/funcargs.py b/py/test/funcargs.py index f1c5d2708..ec30c353e 100644 --- a/py/test/funcargs.py +++ b/py/test/funcargs.py @@ -116,33 +116,21 @@ class FuncargRequest: self.addfinalizer(lambda: teardown(val), scope=scope) return val - def call_next_provider(self): - if not self._provider[self._argname]: - raise self.Error("no provider methods left for %r" % self._argname) - next_provider = self._provider[self._argname].pop() - return next_provider(request=self) - def getfuncargvalue(self, argname): try: return self._funcargs[argname] except KeyError: pass - assert argname not in self._provider - self._provider[argname] = self.config.pluginmanager.listattr( - plugins=self._plugins, - attrname=self._argprefix + str(argname) - ) - # during call_next_provider() we keep state about the current - # argument on the request object - we may go for instantiating - # request objects per each funcargname if neccessary - oldname = self._argname - self._argname = argname - try: - self._funcargs[argname] = res = self.call_next_provider() - except self.Error: + if argname not in self._provider: + self._provider[argname] = self.config.pluginmanager.listattr( + plugins=self._plugins, + attrname=self._argprefix + str(argname) + ) + #else: we are called recursively + if not self._provider[argname]: self._raiselookupfailed(argname) - if oldname: - self._argname = oldname + funcargprovider = self._provider[argname].pop() + self._funcargs[argname] = res = funcargprovider(request=self) return res def _getscopeitem(self, scope): diff --git a/py/test/plugin/conftest.py b/py/test/plugin/conftest.py index ebe8c85c6..a4542a643 100644 --- a/py/test/plugin/conftest.py +++ b/py/test/plugin/conftest.py @@ -9,7 +9,7 @@ def pytest_collect_file(path, parent): # decorate testdir to contain plugin under test def pytest_funcarg__testdir(request): - testdir = request.call_next_provider() + testdir = request.getfuncargvalue("testdir") #for obj in (request.cls, request.module): # if hasattr(obj, 'testplugin'): # testdir.plugins.append(obj.testplugin) diff --git a/py/test/plugin/pytest_restdoc.py b/py/test/plugin/pytest_restdoc.py index f01d9c53f..03cf8c39b 100644 --- a/py/test/plugin/pytest_restdoc.py +++ b/py/test/plugin/pytest_restdoc.py @@ -391,7 +391,7 @@ class TestApigenLinkRole: class TestDoctest: def pytest_funcarg__testdir(self, request): - testdir = request.call_next_provider() + testdir = request.getfuncargvalue("testdir") assert request.module.__name__ == __name__ testdir.makepyfile(confrest="from py.__.misc.rest import Project") for p in testdir.plugins: diff --git a/py/test/testing/test_funcargs.py b/py/test/testing/test_funcargs.py index b34a2e662..086ad0d34 100644 --- a/py/test/testing/test_funcargs.py +++ b/py/test/testing/test_funcargs.py @@ -128,15 +128,20 @@ class TestRequest: assert len(provider) == 1 assert provider[0].__name__ == "pytest_funcarg__something" - def test_request_call_next_provider(self, testdir): + def test_getfuncargvalue_recursive(self, testdir): + testdir.makeconftest(""" + def pytest_funcarg__something(request): + return 1 + """) item = testdir.getitem(""" - def pytest_funcarg__something(request): return 1 - def test_func(something): pass + def pytest_funcarg__something(request): + return request.getfuncargvalue("something") + 1 + def test_func(something): + assert something == 2 """) req = funcargs.FuncargRequest(item) val = req.getfuncargvalue("something") - assert val == 1 - py.test.raises(req.Error, "req.call_next_provider()") + assert val == 2 def test_getfuncargvalue(self, testdir): item = testdir.getitem(""" diff --git a/py/test/testing/test_pickling.py b/py/test/testing/test_pickling.py index 24af46e49..3c11a61dc 100644 --- a/py/test/testing/test_pickling.py +++ b/py/test/testing/test_pickling.py @@ -14,7 +14,7 @@ def setglobals(request): def pytest_funcarg__testdir(request): setglobals(request) - return request.call_next_provider() + return request.getfuncargvalue("testdir") class ImmutablePickleTransport: def __init__(self, request):