* remove redundant call_next_provider method, thus generalizing Request object

* refine according documentation

--HG--
branch : trunk
This commit is contained in:
holger krekel 2009-06-11 19:49:25 +02:00
parent 3f50470c6a
commit a59d602bce
6 changed files with 32 additions and 53 deletions

View File

@ -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

View File

@ -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):

View File

@ -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)

View File

@ -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:

View File

@ -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("""

View File

@ -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):